Java 泛型类中这些语句之间的区别是什么?

Java 泛型类中这些语句之间的区别是什么?,java,generics,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>(); } } 公共类测试{

我还在学习泛型,还有一个问题。假设您有一个通用类:

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>();
    }
}
公共类测试{
公共静态void main(字符串[]args){
测试t1=新测试();
测试t2=新测试();
测试t3=新测试();
}
}
所有的语句都可以编译,但我真的不知道是什么让它们不同。有谁能就这三种说法给我一个简短的解释

Test t1 = new Test();
这里使用的是原始类型。i、 例如,不为您的
泛型cla
s传递
类型参数

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

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

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

  • 测试是原始类型。对泛型测试的引用应参数化
与第一种情况相同,但在调用构造函数时使用的是参数化类型

还有一个类在+Java7版本中运行良好

    Test<String> t4 = new Test<>();
测试t4=新测试();
如果由于类型推断而使用+java 7,则此处没有编译器警告


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

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

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


t2
将在类型检查方面得到更严格的处理。如果编译器有机会利用其泛型
质量,那么该质量也将需要匹配。

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

它有助于添加您可以/不能使用项目的示例(为了便于示例,我将
Test
更改为
ArrayList
):

ArrayList t1=新的ArrayList();
ArrayList t2=新的ArrayList();
ArrayList t3=新的ArrayList();
//第一个列表可以添加任何内容
//编译器不会检查,因为没有泛型
t1.加上(新的整数(“7”));
t1.加上(“你好”);
//第二个列表只能添加字符串
//编译器将检查并抛出任何其他编译错误
t2.添加(新整数(“7”);//不编译
t2.加上(“你好”);
//第三个列表很有趣。。。
//再说一次,你可以添加任何内容
//这是因为泛型(Java…)在编译时被交换掉
//而不是运行时。编译器可以看到实际类型只是
//平面阵列列表
//如果您愿意,这类似于:
//对象o=(字符串)新对象();
//最终的效果是一切都还原为对象
t3.添加(新的整数(“7”);//好的
t3.加上(“你好”);

几乎正确。另外两个只是广告警告,而不是真正的编译错误。我们还应该补充一点,原来的问题遗漏了两个组合:
Test t4=new Test()
,它不会编译,因为它试图将原始类型的引用分配给泛型类型之一;和
Test t5=new Test()
,它在Java 7.+1中使用新的“菱形运算符”进行编译,并且由于Java 7,您还可以编写Test t4=new Test();这相当于t2声明…@yshavit和pgras刚刚添加了它:)
    Test t3 = new Test<String>();
    Test<String> t4 = new Test<>();
    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");