2016-10-06 3 views
0

Ich stieß auf diesen Abschnitt der kommentierten Code auf StackOverflow. Es wird eine Laufzeitausnahme ausgelöst. Der zweite Teil (der nicht kommentierte Abschnitt) wird funktionieren. Ich bin nicht in der Lage, den Unterschied zwischen den beiden zu finden, da beide Methoden Arrays von Objekten zurückgeben. Vielleicht fehlt mir ein grundlegendes Verständnis. Kannst du mir bitte helfen?Array von Strings vs Array von Objekten Java

public class Safevarargs { 

/* 
    static <Object> Object[] asArray(Object... args) { 
     return args; 
    } 

    static <Object> Object[] arrayOfTwo(Object a, Object b) { 
     return asArray(a, b); 
    } 

    public static void main(String[] args) { 
     String[] bar = arrayOfTwo("hi", "mom"); 
    } 
*/ 

    static <Object> Object[] display(Object... args) { 
     return args; 
    } 

    public static void main(String[] args) { 
     String[] str = display("hi", "mom"); 
     System.out.print(str[0]); 
    } 
} 
+1

Was ist die Ausnahme? – Jens

+5

Es ist EXTREM schlecht, einen Namen wie 'Object' für eine generische Typvariable zu verwenden. –

+0

Sie haben einige unnötige Wiederholung. Es gibt keine Möglichkeit, 'AsArray' ist fehlerhaft, aber nicht' display'. – ChiefTwoPencils

Antwort

0

Ich glaube, Sie haben ein Problem mit dem Gießen. Wenn Sie den Teil verwenden

static <Object> Object[] display(Object... args) 

was der Compiler tatsächlich sehen, ist

static <Object> Object[] display(Object[]... args) 

dann weiter es wandelt es in diesem

static <Object> Object[] display(List[]... args) 

Dies könnte Werte zulassen, die nicht in sein sollte dort

Nehmen wir an, Sie machen ein Objekt-Array von String und versuchen, ein int zu ihm hinzuzufügen. Dies würde ein Problem mit den verschiedenen Typen verursachen. Möglicherweise möchten Sie es erneut bearbeiten, ohne das generische Objekt zu verwenden.

Alternativ können Sie das @ SafeVarar-Tag verwenden.

+1

Der Compiler sieht 'Object []', wenn er 'Object ...' betrachtet und zu keinem Zeitpunkt ist 'List' involviert. – Kayaman

0

Dies ist eine interessante Situation hier. In der ersten Instanz beschwert sich Java über das Umwandeln von einem Objektarray in ein Zeichenfolgenarray.

java.lang.ClassCastException: [Ljava.lang.Object; kann nicht in [Ljava.lang.String;

Im zweiten Fall behandelt es es gut. Das Problem scheint eine Art Löschung zu sein. Wenn asArray zurückgegeben wird, gibt es ein Array zurück, das basierend auf seinen Parametern typisiert wurde. Diese Information wird im Kontext von arrayOfTwo gelöscht, wo der Typ einfach Object[] wird, und die Tatsache, dass der Inhalt Zeichenfolgen ist nicht mehr verfügbar.

Werfen Sie einen Blick auf auf Typ löschen und nicht-veränderbare Typen, und die Auswirkungen auf Varargs. Es hat einigen Kontext zu machen auf der Warnung, die der Code, über „mögliche Heap Verschmutzung“ erzeugt:

Safevarargs.java:11: Warnung: [ungeprüft] Mögliche Heap Verschmutzung durch parametrisierte Vararg Typen Object
statische Object [ ] Anzeige (Object ... args) {
^ dem Objekt ein Typ-Variable ist:
Objekt erweitert java.lang.Object in Methode deklariert Anzeige (Object ...)

Aus der Dokumentation :

Heap Pollution tritt auf, wenn sich eine Variable eines parametrisierten Typs auf ein Objekt bezieht, das nicht von diesem parametrisierten Typ ist.

0

Um dieses Problem zu erklären, müssen wir nur wissen, wie das generische in Java funktioniert.Der Compiler verwendet die generischen Typinformationen intern während des Kompilierungsprozesses und generiert bei der Verarbeitung der Quellen typbezogene Fehler. Sobald die Überprüfung abgeschlossen ist, generiert der Compiler vom Typ gelöschter Byte-Code, wobei alle Verweise auf generische Typen durch den jeweiligen Typ gelöscht werden.

in Ihrem zweiten Beispiel wird das kompiliert, um während der Kompilierzeit zu string. Da das asArray jedoch in einem ersten Beispiel von einer anderen generischen Methode aufgerufen wird, wird es während der Kompilierung in Object kompiliert. Daher kann das Objekt [] in der Laufzeit nicht in String [] umgewandelt werden, wodurch die Klassenausnahme ausgelöst wird. hoffe das kann dir helfen