2010-04-22 15 views
24

Creo que obtengo lo que significa no verificando el reparto (de uno a otro tipo diferente), pero ¿qué significa "verificar" el reparto? ¿Cómo puedo verificar el reparto para poder evitar esta advertencia en Eclipse?¿Qué es un yeso no revisado y cómo lo verifico?

+1

Publique el código fuente. –

+12

¡No publique el código! No dejes que te den pescado en lugar de enseñarle a pescar :) No, en serio, debería haber una respuesta genérica para una pregunta genérica, incluso si la pregunta se hace en un estilo amateur. – Mike

Respuesta

28

Unchecked significa que estás (implícita o explícitamente) lanzando desde un tipo genérico a un tipo no calificado o al revés. P.ej. esta línea

Set<String> set = new HashSet(); 

producirá una advertencia.

Por lo general, hay una buena razón para tales advertencias, por lo que debe intentar mejorar su código en lugar de suprimir la advertencia. Cita de Effective Java, 2nd Edition:

Elimine todas las advertencias sin marcar que pueda. Si elimina todas las advertencias, tiene la seguridad de que su código es seguro, lo que es muy bueno para . Significa que no obtendrá un ClassCastException en tiempo de ejecución, y aumenta su confianza de que su programa se comporta como lo desea.

Si no puede eliminar una advertencia, y se puede demostrar que el código que provocó la advertencia es typesafe, entonces (y sólo entonces) suprimir la advertencia con una anotación @SuppressWarnings("unchecked"). Si suprime las advertencias sin primero probar que el código es seguro, solo se está dando un falso sentido de seguridad . El código puede compilarse sin emitir ninguna advertencia, pero todavía puede arrojar un ClassCastException en tiempo de ejecución. Sin embargo, si ignora advertencias sin marcar que sabe que son seguras (en lugar de suprimirlas), no se dará cuenta cuando aparezca una nueva advertencia que represente un problema real. La nueva advertencia se perderá en medio de todas las falsas alarmas que no haya silenciado.

Por supuesto, no siempre es tan fácil eliminar las advertencias como con el código anterior. Sin embargo, sin ver su código, no hay manera de decir cómo hacerlo seguro.

+0

¿Qué hay de este elenco sin control: 'FoodBag bag2 = new FoodBag ();' ' ((FoodBag ) bag2) .setFood (nueva CheeseSandwich());' de un tipo genérico a una ¿tipo genérico? – Datoraki

+0

@Datoraki, ¿podría ser más específico con su pregunta? –

+19

-1 porque la respuesta no aborda la parte de la pregunta "Cómo verificar". Ok, sabemos que debemos verificar el reparto, ** ¿cómo ** lo hacemos? – Mike

39

Para ellaborate más en lo que Pedro escribió:

Yesos de tipos no genéricos a tipos genéricos puede funcionar muy bien en tiempo de ejecución, ya que los parámetros genéricos se borran durante la compilación, por lo que se quedan con un elenco legítimo. Sin embargo, el código puede fallar más tarde con una ClassCastException inesperada debido a una suposición incorrecta con respecto al parámetro de tipo. Por ejemplo:

List l1 = new ArrayList(); 
l1.add(33); 
ArrayList<String> l2 = (ArrayList<String>) l1; 
String s = l2.get(0); 

La advertencia sin comprobar en la línea 3 indica que el compilador no es capaz de garantizar la seguridad de tipos más, en el sentido de que un ClassCastException inesperado puede aparecer dentro somewere más tarde. Y esto sucede en la línea 4, que realiza un lanzamiento implícito.

+5

Esta debería ser la respuesta aceptada – CodyBugstein

0

Un modelo no seleccionado, a diferencia del modelo verificado, no verifica la seguridad del tipo en tiempo de ejecución.

Aquí hay un ejemplo basado en la sección Consider typesafe heterogenous containers de la 3ª ed.de "Effective Java" por Joshua Bloch, pero la clase de contenedor se rompe intencionadamente - almacena y devuelve el tipo incorrecto:

public class Test { 

    private static class BrokenGenericContainer{ 
     private final Map<Class<?>, Object> map= new HashMap<>(); 

     public <T> void store(Class<T> key, T value){ 
      map.put(key, "broken!"); // should've been [value] here instead of "broken!" 
     } 

     public <T> T retrieve(Class<T> key){ 
//   return key.cast(map.get(key)); // a checked cast 
      return (T)map.get(key);  // an unchecked cast 
     } 

    } 

    public static void main(String[] args) { 
     BrokenGenericContainer c= new BrokenGenericContainer(); 
     c.store(Integer.class, 42); 
     List<Integer> ints = new ArrayList<>(); 
     ints.add(c.retrieve(Integer.class)); 
     Integer i = ints.get(0); 
    } 

} 


Si el retrieve() utiliza un fundido sin control-(T)map.get(key) - la ejecución de este programa se conducir a ClassCastException que ocurre en la línea Integer i = ints.get(0). El método retrieve() completará porque el tipo real no se comprobó en tiempo de ejecución:

Exception in thread "main" 
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
    at Test.main(Test.java:27) 


Pero si el retrieve() utiliza un activado Nuestros fundido - key.cast(map.get(key)) - ejecutar este programa conducirá a ClassCastException que ocurre en key.cast(map.get(key)) línea, porque el elenco verificado descubrirá que el tipo es incorrecto y arrojará la excepción. El método retrieve() no completará:

Exception in thread "main" java.lang.ClassCastException: 
              Cannot cast java.lang.String to java.lang.Integer 
    at java.lang.Class.cast(Class.java:3369) 
    at Test$BrokenGenericContainer.retrieve(Test.java:16) 
    at Test.main(Test.java:26) 

Poca diferencia que pueda parecer, pero en el caso de la fundición sin control, un String realizado con éxito su camino en un List<Integer>. En aplicaciones del mundo real, las consecuencias de esto pueden ser ... bueno, severas. En el caso del yeso marcado, el desajuste de tipo se descubrió lo más temprano posible.


Para evitar los moldes sin marcar, advirtiendo, @SuppressWarnings("unchecked") se puede utilizar, si el programador es realmente seguro de que el método es de hecho seguro. La mejor alternativa es usar genéricos y modelos controlados cuando sea posible.

Como Joshua Bloch puso,

... sin marcar advertencias son importantes. No los ignores


En aras de la exhaustividad, this ofertas de respuestas con los detalles Eclipse.

Cuestiones relacionadas