Java Undefined Generics Brackets用法

时间:2014-09-02 23:56:04

标签: java generics arraylist unchecked

我最近完成了AP计算机科学(Java)的在线课程,期末考试中出现了类似这样的问题:

  

其中哪些需要String强制转换才能使用String方法:
  I. ArrayList a = new ArrayList();
  II。 ArrayList<Object> b = new ArrayList<Object>();
  III。 ArrayList<String> c = new ArrayList<String>();

关于这一点让我感到困惑:选项I甚至可以被投币吗?它没有通用定义,除非Java编译器def ArrayList<Object>,那么什么类是E呢?


这是我的测试代码(需要抑制注释,因为这是&#34;未经检查&#34;操作):

ArrayList a = new ArrayList();

@SuppressWarnings("unchecked")
a.add(new Object());

@SuppressWarnings("unchecked")
a.add(new String("test"));

@SuppressWarnings("unchecked")
a.add(null);

System.out.println((String)(a.get(0)));  

无论add()方法的参数是什么,它总是会给编译器错误:

test.java:14: error: <identifier> expected
        a.add(new Object());
             ^

如果我尝试在代码的任何位置添加标识符(例如:a<Object>.add(new Object())),它会提供与以前完全相同的错误。

问题是当没有参数传递给generics参数时实际发生了什么,并且首先可以将任何内容添加到此列表中,更不用说转换为另一个对象了?提前谢谢!

2 个答案:

答案 0 :(得分:1)

您有一个简单的语法错误。 @SuppressWarnings不能用于a.add(x)之类的空间语句,只能用于类声明,方法声明和变量声明。这就是为什么它要求一个标识符,@ SuppressWarnings期望看到这三个中的一个,而不是一个简单的陈述。

   public static void main(String[] args) {
      ArrayList a = new ArrayList();
      a.add(new Object());
      a.add(new String("test" );
      a.add(null);
      System.out.println((String) (a.get(0)));
   }

代码编译得很好。

那么当您使用原始类型时会发生什么?没有。没有进行类型检查。上面的代码在println语句中生成java.lang.ClassCastException error。当你打算放置一个Object时,你并没有注意到String,并且直到运行时才知道你在println上的强制转换是坏的。< / p>

答案 1 :(得分:0)

如果未指定,则默认为泛型的边界,如果未指定,则默认为对象。

这意味着:

List lst = new ArrayList();

完全等同于:

List<Object> lst = new ArrayList<Object>();

在这样的列表中,可以添加或检索所有内容,因为Java中的所有内容都扩展了Object,除了基元(但随后自动装箱起作用)。

所以,你可以正确地写:

lst.add("String");
lst.add(new Date());
lst.add(new Integer(1));
lst.add(1); // It is converted to an Integer by auto-boxing

你可以正确地写:

String str = (String)lst.get(0);

但是你必须知道可能的运行时转换异常:

String str2 = (String)lst.get(1); // Will give error, cause element 1 is a date.

如果您有一个特定的ArrayList子类,它定义了一个通用绑定,例如:

public class MyList<E extends MyClass> extends ArrayList<E> { 

你仍然可以在没有泛型的情况下使用它:

MyList lst = new MyList();

但它只接受MyClass或MyClass的子类:

lst.add(new MyClass());
lst.add(new MySubClass());
MyClass a = lst.get(0);
MyClass b = lst.get(1);
MySubClass c = (MySubClass)lst.get(1);

但没有别的:

lst.add("String"); // Will give compile time error