用`new`实例化泛型时,包含类型参数之间是否存在实际差异?

时间:2017-11-24 05:57:29

标签: java generics syntax

我开始学习Java,在我的程序中它出现了

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

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

Stack<Integer> s = new Stack();

所有编译并生成我期望的输出。

有什么实际区别吗?哪个更受欢迎?

3 个答案:

答案 0 :(得分:5)

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>是未经检查的转换。&#34; < / p>

在此示例中并未立即清除类型安全性正在丢失,因为虽然创建的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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

没有实际差异。一切都一样。 基本上它只是我们写作的方式。

早期版本的java      <{1}}是必须写的,但现在不是。

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