Java Raw Type和generics交互
如果我有一个Stack类
class Stack {}
现在,如果我这样做:
1) Stack s = new Stack()
2) Stack s = new Stack()
3) Stack s = new Stack()
谁能解释我这些互动(通用原始)会导致什么?
主要是我对第1点的疑问。事实上,如果我这样做,那么它是不安全的,因为该堆栈可以存储除Integer之外的其他类型。 是的,但是如果我有一个push方法并尝试存储除Integer以外的值,那么编译器会阻止我…所以当我有不安全的操作时?
这三个都是完全合法的,因为Stack
和Stack
之间没有实际的运行时差异,但这三个都会导致编译器警告。
Stack s = new Stack()
这将导致“未经检查的转换”警告,因为将原始类型转换为参数化类型通常是不安全的。 但是,在这种情况下这样做是完全安全的:推送Integer
值不会导致任何错误; 推送非Integer
数值将导致类型错误。
Stack s = new Stack()
这是从参数化类型到原始类型的合法转换。 您将能够推动任何类型的价值。 但是,任何此类操作都将导致“未经检查的呼叫”警告。
Stack s = new Stack()
同样,这是合法的,没有隐式转换。 您将能够推动任何类型的价值。 但是,任何此类操作都将导致“未经检查的呼叫”警告。
Stack
引用类型Stack
时,您也可能会收到“原始类型”警告。
所有这些都是不安全的,因为Javagenerics,由于类型擦除 ,只是语法糖。 例如,这是完全有效的Java代码:
Stack s = new Stack (); Stack s2 = (Stack )s; s2.push(3.3d);
Javagenerics的要点是阻止你必须明确关于强制转换对象。 而已。 他们只做那些(除了生成编译器和IDE警告)。
它们仍然有用,可以使您的代码更具可读性,更不容易出错,但最终,在字节代码级别,了解它们没有做任何事情是很重要的。