我仍在学习泛型,并有一个问题。假设你有这个通用类:
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>();
}
}
所有语句都编译但我真的不知道是什么让它们与众不同。任何人都可以就这三个陈述给我一个简短的解释。
答案 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)
他们实际上都创建了相同的对象。唯一的区别在于它们在其余代码中的语法处理方式。
t1
和t3
将以完全相同的方式处理,因为它们属于同一类型 - 它们将被视为具有类Test
的对象,仅此而已。
t2
将得到更严格的处理。如果有一些机会让编译器使用其通用的<String>
质量,那么也需要该质量来匹配。