Java中泛型的理解(三)

主要总结了泛型的一些应用
泛型接口、泛型方法、泛型数组、泛型的嵌套设置、标识接口
一.泛型接口
1.定义方式:
[访问权限]interface 接口名称<泛型标识>{}
interface Info<T>{
    public T getVar();
}
interface Info<T>{
	public T getVar();
}
class InfoImpl implements Info{
	public String getVar(){
		return null;
	}
}

以上的操作并不是子类实现泛型接口的最好操作,最好在实现的时候也指定其具体的泛型类型
2.泛型接口的两种实现方式
第一种:在子类的定义上也声明泛型类型
interface Info<T>{	//在接口上定义泛型
	public T getVar();	//定义抽象方法,抽象方法的返回值就是泛型类型
}
class InfoImpl<T> implements Info<T>{	//定义泛型接口的子类
	private T var;	
	public InfoImpl(T var){
		this.setVar(var);
	}
	public void setVar(T var){
		this.var = var;
	}
	public T getVar(){
		return this.var;
	}
}
public class GenericDemo10{
	public static void main(String[] args){
		InfoI<String> i = null;    //声明接口对象
		i = new InfoImpl<String>("Jack");	//通过子类实例化对象
		System.out.println("内容:"+ i.getVar());
	}
}

第二种:在实现接口的子类不使用泛型声明,则在实现接口的时候直接指定操作类型
interface Info<T>{	//在接口上定义泛型
	public T getVar();	//定义抽象方法,抽象方法的返回值就是泛型类型
}
class InfoImpl implements Info<String>{	//定义泛型接口的子类
	private String var;	
	public InfoImpl(String var){
		this.setVar(var);
	}
	public void setVar(String var){
		this.var = var;
	}
	public String getVar(){
		return this.var;
	}
}
public class GenericDemo11{
	public static void main(String[] args){
		Info i = null;
		i = new InfoImpl("Jack");	//通过子类实例化对象
		System.out.println("内容:"+ i.getVar());
	}
}

二.泛型方法
之前总结泛型方法,这里再给出泛型方法的两个操作
定义方法:
[访问权限]<泛型标识> 泛型标识 方法名称(泛型标识 参数名称){}
class Demo{
	public <T> T fun(T t){	//可以接收任意类型的数据
		return t;
	}
}
public class GenericDemo01{
	public static void main(String[] args){
		Demo d = new Demo();
		String str = d.<String>fun("Jack");
		int i = d.<Integer>fun(30);
		System.out.println("内容:"+ str);
		System.out.println("内容:"+ i);
	}
}

1.通过泛型方法返回类的实例
class Info<T extends Number>{  
	private T var;
	public void setVar(T var){
		this.var = var;
	}
	public T getVar(){
		return var;
	}
}  
public class GenericDemo03{
	public static void main(String[] args){  
		Info<Integer> i = fun(30);
		System.out.println(i.getVar());
	}  
	public static <T extends Number> Info<T> fun(T param){
		Info<T> temp = new Info<T>();
		temp.setVar(param);
		return temp;
	}
	
}  

2.使用泛型方法统一参数类型
某些操作中,希望传递的泛型类型参数是同一种类型,比如加法,此时需要统一参数类型
class Info<T>{  
	private T var;
	public void setVar(T var){
		this.var = var;
	}
	public T getVar(){
		return var;
	}
}  
public class GenericDemo04{
	public static void main(String[] args){  
		Info<String> i1 = new Info<String>();
		Info<String> i2 = new Info<String>();
		i1.setVar("Jack");
		i2.setVar("Rose");
		add(i1,i2);
	}  
	public static <T> void add(Info<T> i1,Info<T> i2){
		System.out.println(i1.getVar()+" love "+i2.getVar());
	}
}  

此时,若传入的参数不统一,编译时会产生错误

三.泛型数组
1.运行时类型查询只适用于原始类型
我们先看一下运行时类型查询的局限性
虚拟机中的对象总有一个特定的非泛型类型,因此,所有的类型查询只产生原始类型,每个泛型程序都会对应一个原始类型程序,由虚拟机翻译
例如:
class Info<T>{  
	private T var;
	public void setVar(T var){
		this.var = var;
	}
	public T getVar(){
		return var;
	}
}  
public class GenericDemo06{
	public static void main(String[] args){  
		Info<String> i = new Info<String>();
		if(i instanceof Info<String>){
			i.setVar("Jack");
		}
	}  
}  

或者强制类型转换:
Info<String> i = (Info<String>) a;
无论何时使用instanceof或者涉及泛型类型的强制类型转换表达式都会看到编译器警告

2.不能创建参数化类型的数组

不能实例化参数化类型的数组,如:
Info<String>[] names = new Info<String>[10];    //ERROR
需要说明的是,这里这是不允许创建这些数组,而声明类型为Info<String>[]的变量是合法的,不过不能用new Info<String>[10]初始化

3.Varargs警告

Varargs:可变参数
向参数个数可变的方法传递一个泛型类型数组的实例:
public class GenericDemo05{
	public static void main(String[] args){
		Integer i[] = fun1(1,2,3,4,5,6);
		fun2(i);	//调用时不用[]
	}
	public static <T> T[] fun1(T...arg){    //接收可变参数
		return arg;	//返回泛型数组		
	}
	public static <T> void fun2(T param[]){
		for(T t:param){
			System.out.print(t+"、");
		}
	}
}  


这里,java虚拟机必须建立一个泛型类型的数组,与第二条相违背,但是在Java SE7中可以使用@SafeVarargs标注fun1()
public class GenericDemo05{
	public static void main(String[] args){
		Integer i[] = fun1(1,2,3,4,5,6);
		fun2(i);	//调用时不用[]
	}
	@SafeVarargs
	public static <T> T[] fun1(T...arg){
		return arg;	//返回泛型数组		
	}
	public static <T> void fun2(T param[]){
		for(T t:param){
			System.out.print(t+"、");
		}
	}
}  

四.泛型嵌套
class Info<T,V>{
	private T var;
	private V value;
	public Info(T var,V value){
		this.setVar(var);
		this.setValue(value);
	}
	public void setVar(T var){
		this.var = var;
	}
	public void setValue(V value){
		this.value = value;
	}
	public T getVar(){
		return this.var;
	}
	public V getValue(){
		return this.value;
	}
}
class Demo<S>{
	private S info;
	publci Demo(S info){
		this.setInfo(info);
	}
	public void setInfo(S info){
		this.info = info;
	}
	public S getInfo(){
		return this.info;
	}
}

现在希望Demo类中info属性是Info类的这种类型,但是Info类本身需要设置两个泛型
这时就用到泛型嵌套了 
class Info<T,V>{
	private T var;
	private V value;
	public Info(T var,V value){
		this.setVar(var);
		this.setValue(value);
	}
	public void setVar(T var){
		this.var = var;
	}
	public void setValue(V value){
		this.value = value;
	}
	public T getVar(){
		return this.var;
	}
	public V getValue(){
		return this.value;
	}
}
class Demo<S>{
	private S info;
	public Demo(S info){
		this.setInfo(info);
	}
	public void setInfo(S info){
		this.info = info;
	}
	public S getInfo(){
		return this.info;
	}
}
public class GenericDemo07{
	public static void main(String[] args){
		Demo<Info<String,Integer>> d = null;	//将Info作为Demo类的泛型类型
		Info<String,Integer> i = null;	//Info指定两个泛型类型
		i = new Info<String,Integer>("Jack",30);	//实例化Info对象
		d = new Demo<Info<String,Integer>>(i);	//在Demo类中设置Info类的对象
		System.out.println("内容一:"+d.getInfo().getVar());
		System.out.println("内容二:"+d.getInfo().getValue());
	}
}

五.标识接口
标识接口是没有任何方法和属性的接口。标识接口不对实现他的类有任何语义上的要求,他仅仅表示实现它的类属于一个特定的类型。
java语言中标识接口有一些著名的应用,比如java.io.Serializable和java.rmi.Remote等接口便是标识接口

参考资料:
java核心技术卷一
java编程思想
李兴华java视频讲解
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值