【问题标题】:Collection with generics带有泛型的集合
【发布时间】:2012-02-14 11:53:38
【问题描述】:

我有一个关于在集合中使用泛型的问题。

ArrayList<Integer> al=new ArrayList<Integer>();

我们知道上面这行意味着ArrayList al 被限制为只能保存整数。所以下面这行给出了编译错误:

al.add("wwww");

但我不明白下面一行是什么意思,

ArrayList al=new ArrayList<Integer>();

我们在声明时不会在左侧给出ArrayList&lt;Integer&gt;。现在下面这行没有给出编译错误:

al.add("wwww");

所以如果我像这样声明

ArrayList al=new ArrayList<Integer>();

这意味着a1 可以接受任何类型?

这两个声明有什么区别?

【问题讨论】:

    标签: java arrays generics collections


    【解决方案1】:

    后一种声明(没有泛型)已过时且不推荐使用。你不应该使用它,它编译只是为了向后兼容。现代 IDE 会在此处生成警告。

    还请注意,Java 仅在编译时强制执行泛型类型,因此从技术上讲,您可以通过一些额外的强制转换将不正确的类型添加到集合中。这就是为什么最好始终使用泛型而不绕过它们。

    【讨论】:

    • ...而您的 IDE(如果您正在使用的话)可能会显示警告。
    • @Axel:+1。我独立地在我的答案中添加了相同的评论,你必须相信我;-)。
    • 出于某种原因,从 7 开始,netbeans 人们默认禁用显示标准 javac 警告。 (并且告诉实习生“修复原始类型警告”的人数显着增加。)
    • 编译它不仅仅是为了向后兼容。很多集合框架是不可能用 Java 编写的(没有 JNI),除非这些东西确实可以编译。
    • @TedHopp - 这很有趣。那么在某些情况下仍然需要原始类型(例如,而不是使用通配符)?
    【解决方案2】:

    使用此代码:

    ArrayList al = new ArrayList<Integer>();
    a1.add("www");
    

    编译器会生成一个警告(你应该注意!),但代码会运行而不会出错。问题在于从a1 中提取数据。如果你“知道”它包含 Integer 值,你可以这样做:

    Integer val = (Integer) a1.get(index);
    

    但是当你点击"www" 元素时,你会得到一个ClassCastException。泛型旨在将此类错误转移到编译时间,而不是强迫可怜的开发人员追踪 String 值是如何在 Integer 数组列表中结束的。

    【讨论】:

      【解决方案3】:

      后面的声明基本同:

      ArrayList<Object> al=new ArrayList<Object>();
      

      因此接受任何对象。不应该使用,可以使用,让Java向后兼容(Java1.5之前)。

      【讨论】:

        【解决方案4】:

        你应该这样写ArrayList&lt;Integer&gt; al=new ArrayList&lt;Integer&gt;(); 以避免将其他类型的对象添加到列表中,因为你会看到错误编译时间。当然你可以使用ArrayList al=new ArrayList&lt;Integer&gt;();,但是你必须小心。换句话说,总是使用第一个 :D

        【讨论】:

          【解决方案5】:

          泛型是通过类型擦除实现的:泛型类型信息仅在编译时出现,之后由编译器擦除。因此,ArrayList al 声明让编译器接受任何类型。这是关于这个主题的java doc

          【讨论】:

            【解决方案6】:

            这种声明是允许向后兼容的。因此,例如,您可以将通用列表传递给旧式库中的方法,该方法仅接受原始列表:

            List<Integer> list = new ArrayList<Integer>();
            OldStyledClass.method(myArray);
            

            方法声明如下:

            public static void method(List list)...
            

            在这种情况下,您在 java.util.Collections 中有一些特殊的实用程序方法。所以你可以传递给这个方法保护列表:

            OldStyledClass.method(Collections.checkedList(myArray, Integer.class));
            

            如果方法尝试将其他类型的对象放入您的列表对象中,您将立即获得 ClassCastException。

            【讨论】:

              猜你喜欢
              • 2023-03-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-06-11
              • 2019-12-10
              • 2017-04-28
              • 1970-01-01
              相关资源
              最近更新 更多