繁体   English   中英

当用`new`实例化泛型时,包括类型参数与否之间有任何实际区别吗?

[英]When instantiating generics with `new`, is there any practical difference between including the type parameter or not?

我开始学习Java,并且在我的程序中

Stack<Integer> s = new Stack<Integer>();

Stack<Integer> s = new Stack<>();

Stack<Integer> s = new Stack();

全部编译并产生我期望的输出。

有实际区别吗? 哪个是首选?

Stack<Integer> s = new Stack<Integer>();

首次引入泛型时,Java 5和Java 6需要这种形式。 但是自Java 7起,它变得比必需的更为冗长。

Stack<Integer> s = new Stack<>();

这种形式是Java 7中引入的,与上面的形式等效,只是编译器会推断类型,因此程序员无需重复该形式。 这是首选形式。

Stack<Integer> s = new Stack();

这使用的是原始类型 ,这很糟糕。 允许与Java 5之前的版本向后兼容,但是编译器会抱怨将原始Stack分配给通用类型的Stack<Integer>是“未经检查的转换”。

在此示例中,尚不清楚类型安全性正在丢失,因为尽管创建的Stack是原始Stack<Object> ,但未保存对原始原始Stack引用,并且Stack不允许您传递参数来填充它,但是这种情况可能在其他类型(例如ArrayList

List<Integer> numbers = List.of(12, 34, 56);
List<String> names = new ArrayList(numbers); // "unchecked conversion" warning
for (String name : names) {    // ClassCastException
    System.out.println(name);
}

即使使用Stack如果我们拆分了创建和分配,问题仍然很明显:

Stack rawStack = new Stack();           // create Stack of raw types
Stack<String> typedStack = rawStack;    // "unchecked conversion" to
                                        //     strongly-typed Stack
rawStack.push(123);                     // push an Integer
typedStack.pop();                       // ClassCastException

在这种情况下,我们保留了对原始原始堆栈的引用,这使我们违反了类型安全性。 您可能会说:“好吧,我永远都不会这样做,”但是创建它的强类型的替代方法是new Stack<>() ,它只是另外两个字符。

这三种实现方式没有任何区别。 对于编译时错误,编译器将在声明变量的同时查看左侧提供的详细信息。 我已经在Eclipse和IntelliJ编辑器中看到了区别,在Eclipse编辑器中自动完成会产生Stack<Integer> s = new Stack<Integer>(); 而在IJ中,自动完成会产生Stack<Integer> s = new Stack<>();

使用Stack<Integer> s = new Stack(); 编译器将给出警告,未经检查的分配。

没有实际的区别。 都一样 基本上,这只是我们写作的方式。

java Stack<Integer> s = new Stack<Integer>();早期版本Stack<Integer> s = new Stack<Integer>(); 是必须写的,但现在不是。

根据我
Stack<Integer> s = new Stack<>(); 是最好的方法,因为您在这里不会收到任何警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM