2009-07-30 22 views
7

Si tengo una clase PilaJava Raw Tipo y genéricos interacción

class Stack<E> {} 

ahora si hago:

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

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

3) Stack s = new Stack()

¿alguien puede explicarme cuáles son estas interacciones (gener ic < -> raw) ¿causas?

Principalmente mi duda es en el punto 1. De hecho, si hago eso la asignación no es segura porque esa pila puede almacenar tipos distintos a Integer. Sí, pero si tengo un método push e intento almacenar un valor distinto a un Entero, el compilador me detiene ... ¿así que cuándo tendría esa operación insegura?

+0

No lo entiendo - ¿quieres tener una pila donde puedes empujar otras cosas, enteros (por ejemplo, enteros y dobles) o quieres usar la pila solo con un tipo (entero) y dejar que el compilador ¿ayudarte? –

+1

No, quiero una pila con un tipo y quiero saber qué sucede si hago asignaciones. – xdevel2000

Respuesta

6

Todos ellos son inseguros porque los genéricos de Java, en virtud de type erasure, son simplemente azúcar sintáctica. Por ejemplo, esto es totalmente válida código Java:

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

El punto de genéricos de Java es que dejar de tener que estar explícita Conversión de objetos. Eso es. No hacen nada más que eso (excepto generar compiladores y advertencias IDE).

Todavía son útiles y pueden hacer que su código sea mucho más legible y menos propenso a errores, pero en última instancia, a nivel de código de bytes, es importante comprender que no están haciendo nada.

+0

no es el caso de OP # 2 uno donde el compilador es lo suficientemente inteligente como para inferir los argumentos de tipo genérico para s? –

+0

Sí, pero en el punto 1, el compilador me avisa si intento poner (con una operación de inserción) un objeto que no sea un Entero. Entonces, puede ser que los genéricos no sean solo un 'azúcar sintáctico', sino que el punto 1 también cambia el comportamiento del compilador (la semántica). Entonces, de nuevo, no entiendo dónde está el inseguro ... ¿Debería darme una explicación más analítica? – xdevel2000

7

Los tres son perfectamente legales, ya que no existe una diferencia de tiempo de ejecución real entre Stack y Stack<Integer>, pero los tres darán lugar a advertencias del compilador.

Stack<Integer> s = new Stack() 

Esto dará lugar a una advertencia de "conversión sin control", ya que no es seguro en general para convertir un tipo de prima a un tipo parametrizado. Sin embargo, es perfectamente seguro hacerlo en este caso: presionar Integer valores no causará ningún error; presionar valores que no sean Integer causará un error de tipo.

Stack s = new Stack<Integer>() 

Esta es una conversión legal de un tipo parametrizado a un tipo sin procesar. Podrás presionar el valor de cualquier tipo. Sin embargo, cualquier operación de este tipo dará como resultado una advertencia de "llamada sin marcar".

Stack s = new Stack() 

Una vez más, esto es legal, sin conversión implícita. Podrás presionar el valor de cualquier tipo. Sin embargo, cualquier operación de este tipo dará como resultado una advertencia de "llamada sin marcar".

También puede recibir una advertencia de "tipo sin formato" siempre que se refiera al tipo Stack.