java 泛型编程学习

先发布,以后有空再修改。。。

第一次看到《java核心技术卷一》中关于泛型这部分的时候感觉很复杂,似乎有说不完的约束条件,让人难以理解。当时只是囫囵吞枣般过了一遍,也没有看出个什么来。现在是时候回过头来认真学习学习这方面的知识啦。在这里记录一下JAVA泛型中比较难理解的部分。

泛型表达式的类型擦除

按照书中的例子:

class Pair<T>{
	public Pair(){
	first=null;
	second=null;
	}
	public Pair(T _first,T _second){
		first=_first;
		second=_second;
	}
	public void setFirst(T _first){
		first=_first;
	}
	public void setSecond(T _second){
		second=_second;
	}
	public T getFirst(){
		return first;
	}
	public T getSecond(){
		return second;

	}
	public String toString(){
		return "First:" +first + "	Second:"+second;
		
	}
	private T first;
	private T second;
}

书中提到:虚拟机中是没有泛型类型对象——所有对象都属于普通类。也就是说经过编译之后的字节码文件中是没有“泛型”这个概念的。

因为T是一个无限定的变量,所以上面的代码中的类型T,可以直接用Object来代替,Object是所有类的超类。无论是Pair<String>或者Pair<Integer>,编译后,它们都将变成Pair<Object>

如果类型限定是多个接是多个接口,如果下面的例子:

public class Interval<T extends Comparable & Serializable>{
	public Interval(T first,T second){
		if(first.compareTo(second)<=0){lower=first;upper=second;}
		else {lower=second;upper=first;}
	}
	...
	private T lower;
	private T upper;
}

那么编译器在编译的时候,是按接口出现的顺序来进行替换的。如上面,类型T将会被用Comparable来替换。如果要用到类型的Serializable接口的时候,编译会在对应的地方加入强制转换语句。同样,如果限定为: T extends Serializable & Comparable的话,类型T将会被用Serializable来替换。因此,作者说了,为了提高效率,应该将标签接口(没有方法的接口,比如Cloneable)放在边界列表的末尾。

作者还提到编译在处理(翻译)泛型表达式的时候的一些细节问题:

当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换。例如:

Pair<Employee> buddies=...;
Employee buddy=buddies.getFirst();

擦除类型之后将返回Object类型(假设类型T是没有限定的),编译器自动插入Employee的强制类型转换,也就是说,编译器把这个方法的调用翻译成了两条虚拟机指令:

Employee buddy=(Employee)buddies.getFirst();

  

1。对原始方法(也就是擦除之后的)Pair.getFirst()的调用,这个方法返回一个Object对象。

2。将返回的Object类型的对象强制转换为Employee。

通配符:

直观地讲,带有超类型限定的通配符声明的对象,可以对其进行写入操作。

而带有子类型限定的通配符声明的对象,可以对其进行读取操作。

原文地址:https://www.cnblogs.com/mosmith/p/4165873.html