10

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

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>();
    }
}

所有的语句都可以编译,但我真的不知道是什么让它们不同。谁能给我简要解释一下这三个陈述。

4

3 回答 3

9
Test t1 = new Test();

在这里,您使用的是Raw 类型。即,不Type argument为您generic clas的 s 传递一个。

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

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

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

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

    Test t3 = new Test<String>();

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

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

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

还有另一个类在 +java 7 版本中运行良好。

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

如果由于类型推断而使用 + java 7,则此处没有编译器警告

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

于 2013-02-22T11:45:52.740 回答
3

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

它有助于添加您可以/不能对您的项目做什么的示例(为了便于示例,我已更改为)TestArrayList

    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");
于 2013-02-22T11:57:22.930 回答
2

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

t1并且t3将被以完全相同的方式处理,因为它们是相同的类型 - 它们将被视为具有 class 的对象Test,仅此而已。

t2在类型检查方面将受到更严格的对待。如果编译器有机会利用其通用<String>质量,那么也需要匹配该质量。

于 2013-02-22T11:53:08.800 回答