class A {
private String a;
public void setA (String a){
this.a = a;
}
public String getA(){
return a;
}
}
class B<T>{
private T t;
public void set(T t){
this.t = t;
}
public T get (){
return <T> t;
}
}
import java.util.Arrays;
public class TestAB {
public class TestAB {
public static void main(String[] args) {
B<A> b = new B<A>();
b.set(new A());
A aa = b.get();
aa.setA("abc");
System.out.println(aa.getA());
System.out.println(Arrays.toString(b.getClass().getTypeParameters()));
}
}
输出:
abc
[T]
问:B中的get()方法虽然进行转型,但因为擦除的作用,其实只是将Object转为Object,那么我们在TestAB中调用
A a = b.get();时为什么不需要进行(A)强制转型就能赋值?
这个问题纠结了好久,希望有人帮我解释一下。
------解决方案--------------------
首先你要知道对象的强制类型转换,只是告诉编译器对象类型而已,本身并没有修改这个对象,但是如果不这么做,编译器并不知道对象的类型
比如Object obj = "something"
String str = obj <----------编译器不会让你这么做,即使你知道obj其实是String类型,但是你声明变量的时候告诉编译器obj是Object类型的,所以编译器认为一个String类型的变量不能指向一个Object类型的对象。
然而String str = (String) obj;这样可以,因为你告诉编译器,obj就是String类型的,那么编译器就不会觉得你在进行错误的操作了。
泛型也是同样的道理,只是给编译器看的,比如你说B<A> b = new B<A>();那么b就只能处理A类型的对象,如果你b.set(一个不是A类型的对象),那编译器会报错,它不会让你这么做,有了这层保护,那当你get的时候,编译器就确定你给它的对象肯定是A类型,所以get返回的时候,会自动把Object类型当做A类型来对待,就不需要你再告诉编译器这个返回值是什么类型了。