unused suppresswarnings statement significa serial rawtypes que empty deprecation java generics unchecked suppress-warnings

statement - ¿Qué es SuppressWarnings("unchecked") en Java?



@suppresswarnings("rawtypes") (9)

En algún momento al mirar a través del código, veo que muchos métodos especifican una anotación:

@SuppressWarnings("unchecked")

¿Qué significa esto?


A veces, los genéricos de Java simplemente no le permiten hacer lo que quiere, y necesita decirle al compilador de manera efectiva que lo que está haciendo realmente será legal en el momento de la ejecución.

Por lo general, me parece un problema cuando me estoy burlando de una interfaz genérica, pero también hay otros ejemplos. Por lo general, vale la pena tratar de encontrar una manera de evitar la advertencia en lugar de suprimirla (las Preguntas frecuentes de Java Genéricos ayudan aquí), pero a veces, incluso si es posible, hace que el código se deforme tanto que eliminar la advertencia es mejor. Siempre agregue un comentario explicativo en ese caso!

Las mismas preguntas frecuentes sobre genéricos tienen varias secciones sobre este tema, comenzando con "¿Qué es una advertencia" sin marcar "?" - Vale la pena leerlo.


En Java, los genéricos se implementan mediante el borrado de tipos. Por ejemplo, el siguiente código.

List<String> hello = List.of("a", "b"); String example = hello.get(0);

Se compila a lo siguiente.

List hello = List.of("a", "b"); String example = (String) hello.get(0);

Y List.of se define como.

static <E> List<E> of(E e1, E e2);

Que después se borra el tipo.

static List of(Object e1, Object e2);

El compilador no tiene idea de qué son los tipos genéricos en tiempo de ejecución, por lo que si escribe algo como esto.

Object list = List.of("a", "b"); List<Integer> actualList = (List<Integer>) list;

Java Virtual Machine no tiene idea de qué son los tipos genéricos mientras se ejecuta un programa, por lo que este compila y ejecuta, como para Java Virtual Machine, este es un tipo de conversión a List (esto es lo único que puede verificar, por lo que solo verifica eso) .

Pero ahora agregue esta línea.

Integer hello = actualList.get(0);

Y JVM lanzará una inesperada ClassCastException , ya que el compilador de Java insertó una conversión implícita.

java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.lang.Integer

Una advertencia unchecked le dice a un programador que una conversión puede hacer que un programa lance una excepción en otro lugar. La supresión de la advertencia con @SuppressWarnings("unchecked") le dice al compilador que el programador cree que el código es seguro y que no causará excepciones inesperadas.

¿Por qué querrías hacer eso? El sistema de tipos Java no es lo suficientemente bueno para representar todos los patrones de uso de tipos posibles. A veces, puede saber que un reparto es seguro, pero Java no proporciona una manera de decirlo: para ocultar advertencias como esta, se puede usar @SupressWarnings("unchecked") , para que un programador pueda concentrarse en advertencias reales. Por ejemplo, Optional.empty() devuelve un singleton para evitar la asignación de opciones vacías que no almacenan un valor.

private static final Optional<?> EMPTY = new Optional<>(); public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; }

Esta conversión es segura, ya que el valor almacenado en un opcional vacío no se puede recuperar, por lo que no hay riesgo de excepciones de conversión de clase inesperadas.


Es una anotación para suprimir las advertencias de compilación sobre operaciones genéricas no verificadas (no excepciones), tales como conversiones. Básicamente, implica que el programador no quiso que se le notificara acerca de estos de los que ya estaba al compilar un bit de código en particular.

Puedes leer más sobre esta anotación específica aquí:

SuppressWarnings

Además, Oracle proporciona documentación tutorial sobre el uso de anotaciones aquí:

Annotations

Como lo ponen,

"La advertencia ''no verificada'' puede aparecer al interactuar con el código heredado escrito antes del advenimiento de los genéricos (discutido en la lección titulada Genéricos)".


La anotación SuppressWarning se utiliza para suprimir las advertencias del compilador para el elemento anotado. Específicamente, la categoría unchecked permite la supresión de las advertencias del compilador generadas como resultado de conversiones de tipo no comprobadas.


Por lo que sé, por ahora tiene que ver con suprimir las advertencias sobre los genéricos; los genéricos son una nueva construcción de programación que no se admite en versiones JDK anteriores a JDK 5, por lo que cualquier combinación de las construcciones antiguas con las nuevas podría generar algunos resultados inesperados.

El compilador advierte al programador al respecto, pero si el programador ya lo sabe, puede desactivar esas advertencias temidas usando SuppressWarnings.


Puede suprimir las advertencias del compilador y decirle a los genéricos que el código que usted escribió es legal de acuerdo con ello.

Ejemplo:

@SuppressWarnings("unchecked") public List<ReservationMealPlan> retreiveMealPlan() { List<ReservationMealPlan> list=new ArrayList<ReservationMealPlan>(); TestMenuService testMenuService=new TestMenuService(em, this.selectedInstance); list = testMenuService.getMeal(reservationMealPlan); return list; }


Simplemente: es una advertencia mediante la cual el compilador indica que no puede garantizar la seguridad del tipo.

Método de servicio JPA por ejemplo:

@SuppressWarnings("unchecked") public List<User> findAllUsers(){ Query query = entitymanager.createQuery("SELECT u FROM User u"); return (List<User>)query.getResultList(); }

Si no anotara las @SuppressWarnings ("sin marcar") aquí, tendría un problema con la línea, donde quiero devolver mi Lista de resultados.

En los medios de seguridad de tipo de método abreviado: un programa se considera seguro de tipo si se compila sin errores ni advertencias y no genera ninguna excepción de clase de evento en tiempo de ejecución.

Me baso en http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals.html


También podría significar que la versión actual del sistema de tipo Java no es lo suficientemente buena para su caso. Hubo varias proposiciones / hacks de JSR para arreglar esto: tokens de tipo, Super Type Tokens , Class.cast ().

Si realmente necesita esta supresión, redúzcala lo más posible (por ejemplo, no la coloque en la propia clase o en un método largo). Un ejemplo:

public List<String> getALegacyListReversed() { @SuppressWarnings("unchecked") List<String> list = (List<String>)legacyLibrary.getStringList(); Collections.reverse(list); return list; }


Un truco es crear una interfaz que amplíe una interfaz base genérica ...

public interface LoadFutures extends Map<UUID, Future<LoadResult>> {}

Entonces puedes comprobarlo con instanceof antes del elenco ...

Object obj = context.getAttribute(FUTURES); if (!(obj instanceof LoadFutures)) { String format = "Servlet context attribute /"%s/" is not of type " + "LoadFutures. Its type is %s."; String msg = String.format(format, FUTURES, obj.getClass()); throw new RuntimeException(msg); } return (LoadFutures) obj;