泛型类中这些语句之间有什么区别?

时间:2013-02-22 11:41:36

标签: java generics

我仍在学习泛型,并有一个问题。假设你有这个通用类:

public class Test<T> {

    public static void main (String[] args) {
        Test t1 = new Test();
        Test<String> t2 = new Test<String>();
        Test t3 = new Test<String>();
    }
}

所有语句都编译但我真的不知道是什么让它们与众不同。任何人都可以就这三个陈述给我一个简短的解释。

3 个答案:

答案 0 :(得分:9)

Test t1 = new Test();

您使用的是原始类型。即,没有为Type argument传递generic clas

编译器应该在这里给你一个警告

  

测试是原始类型。应该参考通用类型Test      参数

    Test<String> t2 = new Test<String>();

这里你使用的是泛型。将String作为type argument传递给您的generic class

    Test t3 = new Test<String>();

编译器也应该在这里给你一个警告:

  
      
  • 测试是原始类型。对泛型类型Test的引用应该参数化
  •   

与第一种情况相同,但在调用构造函数时使用的是参数化类型。

还有另一个类可以在+ java 7版本中正常工作。

    Test<String> t4 = new Test<>();

如果因类型推断

而使用+ java 7,则此处没有编译器警告

在这种情况下,由于引入了type inference泛型类型,因此您不需要在构造函数调用期间提供泛型类型。

答案 1 :(得分:3)

泛型为您提供编译时类型检查。

有助于添加您对项目可以做什么/不做什么的示例(为了便于举例,我已将Test更改为ArrayList):

    ArrayList t1 = new ArrayList();
    ArrayList<String> t2 = new ArrayList();
    ArrayList t3 = new ArrayList<String>();

    // First list can have ANYTHING added to it
    // Compiler won't check because no generics
    t1.add(new Integer("7"));
    t1.add("Hello");

    // Second list can only have Strings added to it
    // Compiler will check and throw compile error for anything else
    t2.add(new Integer("7"));   // doesn't compile
    t2.add("Hello");

    // Third list is interesting...
    // Again, can have ANYTHING added to it
    // This is because generics (in Java...) are swapped out at COMPILE time
    //   rather than RUNTIME. The compiler can see that the actual type is just
    //   plain ArrayList
    // If you like, it's similar to doing: 
    //   Object o = (String) new Object(); 
    // The net-effect is everything reduced back to Object
    t3.add(new Integer("7"));  // fine
    t3.add("Hello");

答案 2 :(得分:2)

他们实际上都创建了相同的对象。唯一的区别在于它们在其余代码中的语法处理方式。

t1t3将以完全相同的方式处理,因为它们属于同一类型 - 它们将被视为具有类Test的对象,仅此而已。

在类型检查方面,

t2将得到更严格的处理。如果有一些机会让编译器使用其通用的<String>质量,那么也需要该质量来匹配。