2016-02-05 8 views
7

Der folgende Code kompiliert beide Testmethoden mit javac in JDK7, aber JDK8 kompiliert nur die Methode willCompile.Migration von Java 7 nach Java 8 - Kompilierungsfehler

die Fehler für willNotcompile sind: "Die Methode method (Class<T>) in der Art Klasa nicht anwendbar für die Argumente ist (Class)."

@Test 
public void willCompile() throws InstantiationException, IllegalAccessException { 
    Class klass = getObject(Class.class); 
    method(klass); 
} 

@Test 
public void willNotCompile() throws InstantiationException, IllegalAccessException { 
    method(getObject(Class.class)); 
} 

<T> ResponseEntity<T> method (Class<T> klasa) { 
    return new ResponseEntity<T>(HttpStatus.OK); 
} 
public static <T> T getObject(Class<T> clazz) throws IllegalAccessException, InstantiationException { 
    return clazz.newInstance(); 
} 
+1

Die 'willCompile()' verwendet Rawtypes, dies wird nur für alten Code unterstützt – Ferrybig

+2

[Was ist ein Rohtyp und warum sollten wir ihn nicht verwenden?] (Http://stackoverflow.com/questions/2770321/ what-is-a-row-type-und-why-shallnt-we-use-it) – Tunaki

+1

[Zieleingabe in verschachtelten Aufruf- und Rohtypen] (http://stackoverflow.com/a/26285613/2711488) – Holger

Antwort

5

Die oben genannten kompiliert, weil es RawTypes verwendet.

Die untere ist nicht, weil Ihre Methode akzeptiert nur eine Class<T>, aber Sie gaben es eine Class. Mithilfe von Reflection können Sie die generischen Typen einer Klasse nicht angeben, sodass getObject ein unformatiertes Klassenobjekt zurückgibt.

Die einzige Lösung für das Problem ist das Casting des Return-Ergebnisses.

method((Class<?>)getObject(Class.class)); 

Aber während diese Lösung löst das Problem der Laufzeit immer noch Probleme mit der Tatsache erhalten, dass Sie keine neue Instanzen von Class erstellen können.

JDK 7 war weniger streng in diesem Vergleich und gegossenem das Rückergebnis Class in ein Class<?> hinter den Kulissen so wurde der Code zu kompilieren erlaubt.

Nach Holger JDK 7 schaltet sich aus, Generika-Typen für die ganzen Linien und verwendet rohen Typen für das Rückergebnis, was bedeutet, dass Verfahren zur Herstellung ein Class bekommt und gibt ein ResponseEntity.

+0

Korrekt, abgesehen von der Tatsache, dass 'getObject()' nicht das rohe Klassenobjekt, sondern die Instanz eines Objekts zurückgibt. Obwohl die Kompilierung in Ordnung ist (Sie sollten zumindest eine Warnung erhalten), wird sie in der Laufzeit anywya fehlschlagen. –

+0

danke. Ich weiß, dass Sie keine neue Instanz der Klasse erstellen können (es wird Ausnahme auslösen), aber es war nur eine schnelle Implementierung, um die Kompilierungsregeln nicht Laufzeit zu überprüfen. – user3364192

+1

Tatsächlich hat Java 7 "Class" nicht in "Class " umgewandelt, es hat die generische Typüberprüfung für den gesamten Ausdruck deaktiviert und rohe Typen während des gesamten Vorgangs verwendet. Daher könnten Sie mit noch mehr generischen Fehlern in der nachfolgenden Verwendung davonkommen, wenn die Eingabe ein unformatierter Typ ist. – Holger