Pregunta

El operador diamante en java 7 permite que el código como el siguiente:

List<String> list = new LinkedList<>();

Sin embargo en Java 5/6, puedo escribir simplemente:

List<String> list = new LinkedList();

Mi comprensión de tipo de borrado es que estos son exactamente los mismos. (El genérica consigue quitado durante la ejecución de todos modos).

¿Por qué molestarse con el diamante en absoluto? ¿Qué nueva funcionalidad de seguridad / Tipo tampoco permite? Si no se dió ninguna funcionalidad nueva, ¿por qué lo mencionan como una característica? Está viciado mi comprensión de este concepto?

¿Fue útil?

Solución

El problema con

List<String> list = new LinkedList();

es que en el lado de la mano izquierda, está utilizando el genérico tipo List<String> donde en el lado derecho está utilizando el prima tipo LinkedList. tipos primas en Java efectivamente sólo existen para compatibilidad con el código pre-genéricos y nunca se deben utilizar en el nuevo código a menos que sea absolutamente necesario.

Ahora, si Java genéricos tenido desde el principio y no tenía tipos, tales como LinkedList, que fueron creados originalmente antes de que tuviera genéricos, probablemente podría haber hecho para que el constructor para un tipo genérico infiere automáticamente su tipo parámetros de la parte izquierda de la asignación si es posible. Pero no fue así, y debe tratar tipos primas y tipos genéricos de forma diferente para la compatibilidad hacia atrás. Eso les deja tener que hacer un ligeramente diferente , pero igualmente conveniente, forma de declarar una nueva instancia de un objeto genérico sin tener que repetir sus parámetros de tipo ... el operador de diamantes.

En cuanto a su ejemplo original de List<String> list = new LinkedList(), el compilador genera una advertencia de que la asignación porque debe. Considere lo siguiente:

List<String> strings = ... // some list that contains some strings

// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);

Los genéricos existe para proporcionar protección en tiempo de compilación en contra de hacer las cosas mal. En el ejemplo anterior, utilizando el tipo de prima significa que usted no obtiene esta protección y obtendrá un error en tiempo de ejecución. Es por esto que no se debe utilizar tipos primas.

// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);

El operador del diamante, sin embargo, permite que el lado derecho de la asignación a ser definido como un verdadero ejemplo genérico con los mismos parámetros de tipo como el lado izquierdo ... sin tener que escribir los parámetros de nuevo. Se le permite mantener la seguridad de los medicamentos genéricos con casi el mismo esfuerzo que utiliza el tipo de prima.

Creo que la clave que hay que entender es que los tipos de primas (sin <>) no pueden ser tratadas igual que los tipos genéricos. Cuando se declara un tipo de prima, se obtiene ninguno de los beneficios y la comprobación de tipos de productos genéricos. También hay que tener en cuenta que Los genéricos son una parte de uso general del lenguaje Java ... que no sólo se aplican a los constructores sin argumentos de Collections!

Otros consejos

Su comprensión es un poco defectuoso. El operador de diamante es una buena característica, ya que no tiene que repetirse. Tiene sentido para definir el tipo una vez cuando se declara el tipo, pero simplemente no tiene sentido definir de nuevo en el lado derecho. El principio DRY.

Ahora, para explicar toda la pelusa sobre la definición de tipos. Tienes razón en que el tipo se retira en tiempo de ejecución, pero una vez que desea recuperar algo fuera de una lista con el tipo de definición que recuperarlo como el tipo que haya definido cuando se declara la lista de lo contrario se perdería todas las características específicas y sólo la tienen objeto cuenta, excepto cuando se había lanzado el objeto recuperado a su tipo original, que a veces puede ser muy complicado y el resultado en un ClassCastException.

El uso de List<String> list = new LinkedList() le conseguirá rawtype advertencias.

Esta línea hace que el [marcar] advertencia:

List<String> list = new LinkedList();

Por lo tanto, las transformaciones pregunta: ¿por qué la advertencia [sin control] no se suprime de forma automática sólo para el caso cuando se crea nueva colección

Creo, que sería mucho más difícil la tarea a continuación, añadir <> función.

UPD . También creo que habría un desastre si fuera legalmente para utilizar tipos primas 'sólo para algunas cosas'

En teoría, el operador de diamantes le permite escribir código más compacto (y legible) por el ahorro de argumentos de tipo repetidas. En la práctica, es sólo dos caracteres confundiendo más que le da nada. ¿Por qué?

  1. No se cuerdo programador utiliza tipos primas en el nuevo código. Por lo que el compilador podría asumir simplemente que al escribir no hay argumentos de tipo que desea que inferir de ellos.
  2. El operador de diamantes no proporciona ninguna información de tipo, sólo dice que el compilador, "no habrá ningún problema". Así omitiendo que se puede hacer ningún daño. En cualquier lugar donde el operador diamante es legal que podría ser "inferir" por el compilador.

En mi humilde opinión, que tiene una forma clara y sencilla para marcar una fuente como Java 7 sería más útil que inventar cosas tan extrañas. En el código tan marcada tipos primas podrían ser prohibidas sin perder nada.

Por cierto., No creo que se debe hacer uso de un interruptor de compilación. La versión Java de un archivo de programa es un atributo del archivo, ninguna opción en absoluto. El uso de algo tan trivial como

package 7 com.example;

podría dejar en claro (se puede preferir algo más sofisticado que incluye una o más palabras clave de lujo). Sería incluso permitir compilar las fuentes escritas para diferentes versiones de Java juntos sin ningún problema. Esto permitiría a la introducción de nuevas palabras clave (por ejemplo, "módulo") o dejar caer algunas características obsoletas (múltiples clases no pública no anidados en un único archivo o en absoluto) sin perder la compatibilidad.

Cuando se escribe List<String> list = new LinkedList();, compilador produce una advertencia "sin control". Es posible ignorarlo, pero si se utiliza para ignorar estas advertencias, también puede pasar por alto la advertencia de que le notifica acerca de un problema de seguridad de tipo real.

Por lo tanto, es mejor escribir un código que no genera advertencias adicionales, y el operador de diamantes le permite hacerlo de forma cómoda y sin repeticiones innecesarias.

Todo dicho en las otras respuestas son válidas, pero los casos de uso no son completamente mi humilde opinión válida. Si uno da de baja guayaba y sobre todo el material relacionado colecciones, el mismo se ha hecho con métodos estáticos. P.ej. Lists.newArrayList () que le permite escribir

List<String> names = Lists.newArrayList();

o con la importación estática

import static com.google.common.collect.Lists.*;
...
List<String> names = newArrayList();
List<String> names = newArrayList("one", "two", "three");

La guayaba tiene otras características muy potentes como este y que en realidad no se puede pensar en mucho usos para el <>.

Habría sido más útil si iban para hacer que el comportamiento del operador de diamante por defecto, es decir, el tipo se infieren desde el lado izquierdo de la expresión o si el tipo de la parte izquierda se infieren desde la banda derecha. Esto último es lo que sucede en Scala.

El punto de operador diamante es simplemente para reducir la tipificación de código cuando se declara tipos genéricos. No tiene ningún efecto en absoluto en tiempo de ejecución.

La única diferencia si especifica en Java 5 y 6,

List<String> list = new ArrayList();

es que se tiene que especificar @SuppressWarnings("unchecked") a la list (de lo contrario obtendrá una advertencia fundido sin marcar). Mi opinión es que el operador de diamante está tratando de hacer que el desarrollo sea más fácil. No tiene nada que ver en la ejecución en tiempo de ejecución de los genéricos en absoluto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top