List
编绎不通过,报错,classname不能转换成Object,为什么??
短回答:Java里面,白马非马。[url]http://cloverprince.iteye.com/blog/707631[/url]
长回答:泛型参数会造成一些“副作用”,会影响“是不是子类”的判定。
比如:
List有一个方法,叫add(Object e),向这个list里加入一个Object类型的对象。
所以:
[code="java"]List lst = ...;
list.add(new Date()); // 这个应该是合法的,因为Date是Object的子类。
[/code]
对于ArrayList:
[code="java"]ArrayList lst2 = new ArrayList();
lst2.add("foo"); // 这个应该是可以的,因为"foo"是String
[/code]
但是,如果假设ArrayList是List的子类,那么:
[code="java"]ArrayList lst2 = new ArrayList();
List lst = lst2; // 假设ArrayList是List的子类,所以可以这样赋值。
lst.add("foo"); // 这个应该是可以的,因为"foo"是String,也是Object
lst.add(new Date()); // 危险!!!!!!
[/code]
看“危险!!”那一行。
对于lst,因为lst是List型,所以这样add是可以的,因为Date是Object的子类。
但是,因为lst2,是ArrayList,这样的add(new Date())又是不行的,因为lst2只能存放String。
问题就出在“假设ArrayList是List的子类”。
根据[b]里氏替换原则[/b],子类必须支持基类的全部操作。但是,这里子类ArrayList显然不能允许基类的这种add(Object)操作。所以不是子类。
事实上List lst = lst2;这一行是编译通不过的,这样做会导致下面那个不安全的操作。
我的博客有进一步讨论。这个争论其实在Java加入泛型的时候就有了。 [url]http://cloverprince.iteye.com/blog/707631[/url]
泛型的前后类型一定要一致!
可以像下面这样
[code="java"]
List list = new ArrayList();
list.add(new Classname());
[/code]
1、Java中的泛型基本上都是在编译器这个层次来实现的,他编译后产生的.class就见不到泛型信息,泛型信息在编译后被擦除了
如:List list = new ArrayList(); 编译后,类型擦除,运行期间jvm只能看到这样的List list = new ArrayList()代码;,所以了,编译器尽可能在编译期间来判断类型是否正确。
2、为了在运行期期间类型安全,假设List a = new ArrayList()可以的话,如果有一个方法 a.add(1);添加一个整形就应该可以吧。但是实际上a的类型为ArrayList类型,在运行的时候,就乱了,你怎么把用于装string类型的list来装整形,就会出现安全问题了。。如果编译不判断的话,到了运行期间就会出大问题了。
3、所以你可以使用通配符 List<?> a = new ArrayList();编译不会出错,但是了你试试添加,编译还是会出错,因为“?”不知道你现在是啥类型
貌似effective java 那本书有详细介绍。可以看看
List ArrayList 可以转 <>里面的类型一直,外面泛型类是继承关系可以的。。