2009-07-30 52 views
7

如果我有一个Stack类Java的原始类型和泛型的相互作用

class Stack<E> {} 

,如果我现在做的事:

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

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

3)Stack s = new Stack()

任何人都可以解释我什么这些互动(生ic < - > raw)的原因?

主要是我的怀疑是对点。事实上,如果我做这样的决定是不安全的,因为该堆栈可以存储其他类型然后整数。是的,但是如果我有一个push方法,并尝试存储 不是整数othern值编译器阻止我......所以当我有不安全的操作?

+0

我不明白 - 你想有一个堆在那里,你可以把其他的东西,然后整数(如整数和双打),或者你想使用堆栈只有一种类型(整数),让编译器帮你? – 2009-07-30 11:41:18

+1

不,我想要一个类型的堆栈,并且想知道如果我执行 那个分配会发生什么。 – xdevel2000 2009-07-30 12:38:31

回答

6

他们都是不安全的,因为Java泛型,凭借type erasure,只是语法糖。例如,这是完全有效的Java代码:

Stack<Integer> s = new Stack<Integer>(); 
Stack<Double> s2 = (Stack<Double>)s; 
s2.push(3.3d); 

Java泛型的一点是,停止你必须明确关于铸造对象。而已。除了生成编译器和IDE警告外,他们什么都不做。

他们仍然有用,可以使你的代码更具可读性和不易出错,但最终,在字节码水平,了解他们什么都没有做是很重要的。

7

这三者都是完全合法的,因为StackStack<Integer>之间没有实际的运行时差异,但所有三者都会导致编译器警告。

Stack<Integer> s = new Stack() 

这将导致“未检查转换”警告,因为将原始类型转换为参数化类型通常不安全。但是,在这种情况下完全可以这么做:推送Integer值不会导致任何错误;推送非Integer值将导致类型错误。

Stack s = new Stack<Integer>() 

这是从参数化类型到原始类型的合法转换。你将能够推动任何类型的价值。但是,任何此类操作都会导致“未检查呼叫”警告。

Stack s = new Stack() 

同样,这是合法的,没有隐式转换。你将能够推动任何类型的价值。但是,任何此类操作都会导致“未检查呼叫”警告。

你也可以得到一个“原料型”警告你指的是类型Stack任何时候。