Frage

Manchmal, wenn sie durch Code suchen, ich sehe viele Methoden eine Anmerkung an:

@SuppressWarnings("unchecked")

Was bedeutet das?

War es hilfreich?

Lösung

Manchmal Java Generics nicht lassen dich einfach nicht tun, was Sie wollen, und Sie benötigen, um effektiv den Compiler zu sagen, dass das, was du tust wirklich wird zur Ausführungszeit legal sein.

ich diese in der Regel einen Schmerz finden, wenn ich eine generische Schnittstelle bin spöttisch, aber es gibt auch andere Beispiele. Es ist in der Regel lohnt sich, einen Weg zur Vermeidung der Warnung zu arbeiten, versuchen, anstatt zu unterdrücken sie (die Java Generics FAQ hilft hier), aber manchmal auch wenn es möglich, biegt sie den Code aus der Form so sehr, dass die Warnung unterdrückt ordentlicheres ist. Fügen Sie immer einen erläuternden Kommentar in diesem Fall!

Die gleiche Generika FAQ hat mehrere Abschnitte zu diesem Thema mit rel="noreferrer"> -?. es lohnt sich eine Lese

Andere Tipps

Es könnte auch bedeuten, dass die aktuelle Java-Typ Systemversion nicht gut genug für Ihren Fall ist. Es gab mehr JSR Sätze / Hacks dieses Problem zu beheben: Typ-Token, super Typ Tokens , Class.cast ().

Wenn Sie wirklich diese supression brauchen, es verengt so weit wie möglich nach unten (zum Beispiel nicht setzt es auf die Klasse selbst oder auf ein langen Verfahren). Ein Beispiel:

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

   Collections.reverse(list);
   return list;
}

Die SuppressWarning Annotation Compiler verwendet, um Warnungen für das annotierte Element zu unterdrücken. Insbesondere erzeugt die unchecked Kategorie ermöglicht Unterdrückung von Compiler-Warnungen als Folge des ungebremsten Typ wirft.

einfach. Es ist eine Warnung, durch die der Compiler zeigt an, dass es nicht die Typsicherheit gewährleisten kann

JPA-Service-Methode zum Beispiel:

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

Wenn ich didn'n die @SuppressWarnings anotate ( „ungeprüft“) hier, es wäre ein Problem mit der Linie hat, wo ich will meine Result zurückzukehren.

Im Kontexttypsicherheit bedeutet. Ein Programm betrachtet wird typsicher, wenn es ohne Fehler und Warnungen kompiliert und wirft keine unerwarteten Classcast s zur Laufzeit

Ich baue auf http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals .html

In Java Generika werden mittels Typ Löschung implementiert. Zum Beispiel der folgende Code.

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

ist mit folgenden zusammengestellt.

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

Und List.of ist wie folgt definiert.

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

, die nach Typ Löschung wird.

static List of(Object e1, Object e2);

Der Compiler hat keine Ahnung, was generische Typen zur Laufzeit sind, so dass, wenn Sie schreiben, so etwas wie diese.

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

Java Virtual Machine hat keine Ahnung, welche generische Typen sind, während ein Programm ausgeführt wird, so dass diese kompiliert und ausgeführt, wie für Java Virtual Machine, ist dies ein Gusstyp List (dies ist die einzige Sache ist, kann es überprüfen, so dass es überprüft nur das).

Aber jetzt diese Zeile hinzufügen.

Integer hello = actualList.get(0);

Und JVM wird eine unerwartete ClassCastException werfen, als Java-Compiler eine implizite Umwandlung eingefügt.

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

Eine unchecked Warnung sagt einen Programmierer, dass eine Besetzung ein Programm verursacht eine Ausnahme woanders zu werfen. Unterdrücken der Warnung mit @SuppressWarnings("unchecked") teilt dem Compiler mit, dass der Programmierer den Code sicher zu sein glaubt und nicht unerwartete Ausnahmen führen.

Warum wollen Sie das tun? Java-Typ-System ist nicht gut genug, um alle mögliche Typ Nutzungsmuster darzustellen. Manchmal können Sie wissen, dass ein gegossenes sicher ist, aber Java bietet keine Möglichkeit, dies zu sagen - zu Warnungen wie diese zu verstecken, kann @SupressWarnings("unchecked") verwendet werden, so dass ein Programmierer auf realen Warnungen konzentrieren können. Zum Beispiel gibt Optional.empty() ein Singleton Zuweisung von leeren optionals zu vermeiden, die keinen Wert speichern.

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

Diese Umwandlung ist sicher, da der Wert in einer leeren optional gespeichert ist, kann nicht mehr abgerufen werden, so dass keine Gefahr unerwarteter Klasse Guss Ausnahmen ist.

Sie können die Compiler-Warnungen unterdrücken und den Generika sagen, dass der Code, den Sie nach ihm legal geschrieben ist.

Beispiel:

@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;
 }

Ein Trick ist, eine Schnittstelle zu schaffen, die eine generische Basis Schnittstelle erweitert ...

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

Dann können Sie es mit instanceof vor der Besetzung prüfen ...

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;

Wie weit ich weiß, jetzt ist es mit Unterdrückung von Warnungen über Generika zu tun hat; Generika sind ein neues Programmierkonstrukt nicht in JDK-Versionen unterstützt früher als JDK 5, so dass alle Mischungen der alten Konstrukte mit den neuen möglicherweise einige unerwartete Ergebnisse darstellen.

Der Compiler warnt den Programmierer darüber, aber wenn der Programmierer bereits kennt, kann sie jene gefürchteten Warnungen aus mit SuppressWarnings drehen.

Eine Warnung, durch die der Compiler zeigt an, dass es nicht die Typsicherheit gewährleisten kann. Der Begriff „ungeprüft“ Warnung ist irreführend. Es bedeutet nicht, dass die Warnung in irgendeiner Weise nicht aktiviert ist. Der Begriff „nicht markiert“ bezieht sich auf die Tatsache, dass der Compiler und das Laufzeitsystem nicht genug Typinformationen haben Sie alle Typprüfungen durchzuführen, die notwendig wären, Typsicherheit zu gewährleisten. In diesem Sinne sind bestimmte Vorgänge „nicht markiert“.

Die häufigste Quelle von „ungeprüft“ Warnungen ist die Verwendung von rohen Typen. „Unkontrolliert“ Verwarnungen, wenn ein Objekt durch eine rohe Art Variable zugegriffen wird, weil die rohe Art nicht genug Typen Informationen liefert alle erforderlichen Typprüfungen durchzuführen.

Beispiel (von ungeprüfter Warnung in Verbindung mit rohen Typen):

TreeSet set = new TreeSet(); 
set.add("abc");        // unchecked warning 
set.remove("abc");
warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.TreeSet 
               set.add("abc");  
                      ^

Wenn die Add-Methode der Compiler aufgerufen wird, nicht weiß, ob es sicher ist, ein String-Objekt in die Sammlung hinzuzufügen. Wenn die TreeSet eine Sammlung ist, die enthält String s (oder ein übergeordneten Typen davon), dann wäre es sicher. Aber von der Art Informationen, die vom rohen Typ bereitgestellt TreeSet der Compiler nicht sagen. Daher ist der Ruf möglicherweise unsicherer und eine „ungeprüft“ Warnung ausgegeben.

„ungeprüft“ Warnungen werden auch gemeldet, wenn der Compiler eine Besetzung, deren Ziel findet Typ entweder eine parametrisierte Typ oder ein Typ-Parameter.

Beispiel (eine ungeprüften Warnung in Verbindung mit einer Umwandlung in einen parametrisierte Typ oder vom Typ mit veränderbarer):

  class Wrapper<T> { 
  private T wrapped ; 
  public Wrapper (T arg) {wrapped = arg;} 
  ... 
  public Wrapper <T> clone() { 
    Wrapper<T> clon = null; 
     try {  
       clon = (Wrapper<T>) super.clone(); // unchecked warning 
     } catch (CloneNotSupportedException e) {  
       throw new InternalError();  
     } 
     try {  
       Class<?> clzz = this.wrapped.getClass(); 
       Method   meth = clzz.getMethod("clone", new Class[0]); 
       Object   dupl = meth.invoke(this.wrapped, new Object[0]); 
       clon.wrapped = (T) dupl; // unchecked warning 
     } catch (Exception e) {} 
     return clon; 
  } 
} 
warning: [unchecked] unchecked cast 
found   : java.lang.Object 
required: Wrapper <T> 
                  clon = ( Wrapper <T>)super.clone();  
                                                ^ 
warning: [unchecked] unchecked cast 
found   : java.lang.Object 
required: T 
                  clon. wrapped = (T)dupl;

Ein gegossener, deren Zieltyp ist entweder ein (Beton- oder beschränktes Wildcard) parametrisierten Typ oder ein Typ-Parameter ist unsicher, ob ein dynamischer Typ Prüfung zur Laufzeit beteiligt ist. Zur Laufzeit ist nur der Typ Löschung verfügbar, nicht der genaue statische Typ, der im Quellcode sichtbar ist. Als Ergebnis wird die Laufzeit Teil der Besetzung basierend auf dem Typ Löschung durchgeführt wird, nicht auf dem genauen statischen Typ.

Im Beispiel würde die Besetzung zu Wrapper prüfen, ob das Objekt von super.clone zurückgegeben wird, ist ein Wrapper, nicht, ob es ein Wrapper mit einer bestimmten Art von Mitgliedern ist. In ähnlicher Weise werden die Modelle auf den Typ-Parameter T Gussobjekt zur Laufzeit zu geben, und wahrscheinlich insgesamt optimierten entfernt. Durch Löschen geben, ist das Laufzeitsystem nicht in der Lage nützliche Typprüfungen zur Laufzeit durchzuführen.

In einer Art und Weise, der Quellcode ist irreführend, denn es legt nahe, dass eine Besetzung auf den jeweiligen Zieltyp durchgeführt wird, während in der Tat des dynamische Teil der Besetzung prüft nur gegen den Typen Löschung des Zieltypen. Die „ungeprüft“ Warnung ausgegeben der Programmierers der Aufmerksamkeit auf diese Diskrepanz zwischen dem statischen und dynamischen Aspekte des Gusses zu ziehen.

Bitte beachten Sie: Was für eine "nicht markiert" Warnung?

@SuppressWarnings Anmerkung ist eine der drei integrierten Annotationen in JDK und neben @Override und @deprecated in Java 1.5 hinzugefügt.

@SuppressWarnings anweisen, die Compiler zu ignorieren oder, angegeben Compiler-Warnung in kommentierten Elementen und alle Programmelemente innerhalb dieses Elements zu unterdrücken. Zum Beispiel, wenn eine Klasse eine besondere Warnung zu unterdrücken, wird kommentiert, dann erzeugt eine Warnung bei einem Verfahren innerhalb dieser Klasse werden auch getrennt werden.

Sie haben vielleicht gesehen @SuppressWarnings ( „ungeprüft“) und @SuppressWarnings ( „serial“), zwei der beliebtesten Beispiele für @SuppressWarnings Anmerkung. Ersteres wird verwendet zur Unterdrückung dieser Warnung zu unkontrolliert Gießen erzeugt durch, während die spätere Warnung verwendet wird, über das Hinzufügen von SerialVersionUID in einer Serializable Klasse zu erinnern.

Lesen Sie mehr: https://javarevisited.blogspot.com/2015/09/what-is-suppresswarnings-annotation-in-java-unchecked-raw-serial.html#ixzz5rqQaOLUa

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top