网页学习体会

  • 首页
  • 个人博客
您的位置: 首页  >  技术问答  >  List list = new ArrayList();

List list = new ArrayList();
分类: 技术问答 • 2022-03-04 22:35:03

List<Object> list = new ArrayList<Classname>();

问题描述:

编绎不通过,报错,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 可以转 <>里面的类型一直,外面泛型类是继承关系可以的。。

答

A是B的子类
但List 不是 List的子类

答

[quote]A是B的子类
但List 不是 List的子类 [/quote]

正解

答

A是B的子类
但List 不是 List的子类
同意

相关推荐

  • List 应用场景 ArrayList LinkedList Vector
  • C# 集合类 :(Array、 Arraylist、List、Hashtable、Dictionary、Stack、Queue)
  • c++常见面试题 转自:http://blog.csdn.net/wdzxl198/article/details/9102759/ 1.new、delete、malloc、free关系 2.delete与 delete []区别 3.C++有哪些性质(面向对象特点) 4.子类析构时要调用父类的析构函数吗? 5.多态,虚函数,纯虚函数 6.求下面函数的返回值(微软) 7.什么是“引用”?申明和使用“引用”要注意哪些问题? 8.将“引用”作为函数参数有哪些特点? 9.在什么时候需要使用“常引用”?  11、结构与联合有和区别? 12、试写出程序结果:  13.重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?  14.有哪几种情况只能用intialization list 而不能用assignment? 15. C++是不是类型安全的? 16. main 函数执行以前,还会执行什么代码? 17. 描述内存分配方式以及它们的区别?  18.分别写出BOOL,int,flo
  • 测试List 跟ArrayList性能的例子
  • Android,ArrayList,List,Set等 Android开发--List与ArrayList区别
  • C#如何对List中的Object进行排序
  • java JSON 序列化类(List 转String)
  • List源码学习之ArrayList
  • ArrayList,Hashtable,List,Dictionary
  • C#学习笔记 1.C#中[],List,Array,ArrayList的区别 OpCodes.Initobj Field :将位于指定地址的值类型的每个字段初始化为空引用或适当的基元类型的 0。 OpCodes.Newobj Field :创建一个值类型的新对象或新实例,并将对象引用(O 类型)推送到计算堆栈上。
  • Java基础private final List mFragmentSet = new ArrayList<>()
  • 为什么List list1 = new ArrayList<>(list) 是浅拷贝?
    • 网站免责声明 网站地图 最新文章 用户隐私 版权申明
    本站所有数据收集于网络,如果侵犯到您的权益,请联系网站进行下架处理。   

    Copyright © 2018-2021   Powered By 网页学习体会    备案号:   粤ICP备20002247号