我开始学习Java,在我的程序中它出现了
Stack<Integer> s = new Stack<Integer>();
和
Stack<Integer> s = new Stack<>();
和
Stack<Integer> s = new Stack();
所有编译并生成我期望的输出。
有什么实际区别吗?哪个更受欢迎?
答案 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>();
是最好的方式,因为你不会在这里收到任何警告。