309 votos

¿Cuál es el punto del operador de diamante en Java 7?

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

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

Sin embargo, en Java 5/6, me puede escribir simplemente:

List<String> list = new LinkedList();

Mi comprensión del tipo de borrado, es que estos son exactamente los mismos. (El genérico se elimina en la ejecución de todos modos). Así que mi pregunta es : ¿por qué molestarse con el diamante? ¿Qué nueva funcionalidad / tipo de seguridad no se permiten? Si no rendimiento de cualquier nueva funcionalidad ¿por qué se menciona como una característica? Es mi entendimiento de este concepto erróneo? Gracias a cualquiera que me ilumine.

363voto

ColinD Puntos 48573

El problema con

List<String> list = new LinkedList();

es que en el lado izquierdo, se utiliza el genérico tipo List<String> donde en el lado derecho está utilizando el crudo tipo LinkedList. Raw tipos en Java de manera efectiva sólo existe para la compatibilidad con pre-genéricos código y nunca debe ser usado en el nuevo código, a menos que es absolutamente necesario.

Ahora, si de Java había genéricos desde el principio y no han tipos, tales como LinkedList, que originalmente fueron creadas antes de que se hubiera genéricos, probablemente podría haber hecho para que el constructor de un tipo genérico deduce automáticamente sus parámetros de tipo de la parte izquierda de la asignación, si es posible. Pero no es así, y debe tratar de raw tipos y los tipos genéricos de forma diferente para la compatibilidad hacia atrás. Que les deja con necesidad de hacer una ligeramente diferente, pero igual de conveniente, la forma de declarar una nueva instancia de un objeto genérico, sin tener que repetir sus parámetros de tipo... el diamante del operador.

En cuanto a tu ejemplo original de List<String> list = new LinkedList(), el compilador genera una advertencia de que la asignación debido a que es debido. Considere esto:

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 medicamentos genéricos existen para proporcionar en tiempo de compilación de protección en contra de hacer algo malo. En el ejemplo anterior, utilizando el crudo tipo significa que no se obtiene esta protección y obtendrá un error en tiempo de ejecución. Esta es la razón por la que usted no debe usar raw tipos.

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

El diamante del operador, sin embargo, permite que el lado derecho de la asignación a definirse como una verdadera instancia genérica con el mismo tipo de parámetros como la izquierda... sin tener que escribir los parámetros de nuevo. Nos permite mantener la seguridad de los medicamentos genéricos con casi el mismo esfuerzo como usar el raw tipo.

Creo que la clave es comprender que los tipos de crudo (sin <>) no pueden ser tratados de la misma como de los tipos genéricos. Cuando se declara un tipo raw, consigue ninguno de los beneficios y el tipo de comprobación de medicamentos genéricos. También tienes que tener en cuenta que los medicamentos genéricos son de propósito general, parte de la del lenguaje Java... que no sólo se aplican a los no-arg constructores de Collections!

27voto

Octavian Damiean Puntos 20620

Su entendimiento es un poco deficiente. El diamante operador es una buena característica, ya que usted no tiene que repetir a ti mismo. Tiene sentido definir el tipo una vez al declarar el tipo, pero simplemente no tiene sentido definir de nuevo en el lado derecho. El principio SECO.

Ahora, para explicar todos los fuzz acerca de la definición de tipos. Tienes razón en que el tipo se retira en tiempo de ejecución, pero una vez que usted quiere recuperar algo de una Lista con el tipo de definición que se la devuelvan como el tipo que hemos definido cuando se declara la lista de lo contrario, se perderían todas las características específicas y sólo las características del Objeto, excepto cuando iba a lanzar el objeto recuperado a su tipo original que a veces puede ser muy complicado y el resultado en una ClassCastException.

Utilizando List<String> list = new LinkedList() conseguirá que rawtype advertencias.

15voto

Roman Puntos 21807

Esta línea produce la advertencia [unchecked]:

List<String> list = new LinkedList();

Entonces, transforma la pregunta: ¿por qué [unchecked] ADVERTENCIA No se suprime automáticamente sólo para el caso cuando se crea la nueva colección?

Creo que sería mucho más difícil tarea entonces agregando <> característica.

UPD: también creo que habría un desastre si fuese legalmente a utilizar tipos de crudo 'sólo para algunas cosas'.

14voto

maaartinus Puntos 12510

En teoría, el diamante del operador le permite escribir más compacto (y legible) código por el ahorro de los repetidos argumentos de tipo. En la práctica, sólo dos confuso caracteres más dar a usted nada. ¿Por qué?

  1. No sane programador utiliza raw tipos en el nuevo código. Por lo que el compilador puede simplemente asumir que al escribir ningún tipo de argumentos que usted desea para inferir de ellos.
  2. El diamante del operador proporciona ningún tipo de información, sólo dice que el compilador, "va a estar bien". Así que por la omisión de lo que no puede hacer ningún daño. En cualquier lugar donde el diamante operador es legal, podría ser "inferido" por el compilador.

En mi humilde opinión, de haber una manera clara y sencilla a la marca de una fuente de Java 7 sería más útil que inventar tales cosas extrañas. En tan marcado de código raw tipos podría ser prohibido sin perder nada.

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

package 7 com.example;

podría hacer claro (quizás prefiera algo más sofisticado, incluyendo uno o más de fantasía palabras clave). Incluso podría permitir a compilar las fuentes escritas para diferentes versiones de Java juntos sin ningún tipo de problemas. Esto permitiría la introducción de nuevas palabras clave (p. ej., "módulo") o la eliminación de algunos obsoletos características (múltiples no-público no-clases anidadas en un único archivo o lo que sea) sin perder la compatibilidad.

6voto

axtavt Puntos 126632

Cuando escribes List<String> list = new LinkedList(); , compilador genera una advertencia "desactivada". Usted puede ignorarlo, pero si usaste para omitir estas advertencias puede extrañes también una advertencia que le informa acerca de un problema de seguridad de tipo real.

Así, es mejor escribir un código que no genera Advertencias adicionales y operador de diamante le permite hacerlo de manera conveniente sin repeticiones innecesarias.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X