2012-08-03 8 views
6

Angenommen, ich habe eine Java-Klasse parametrisiert, die ein privates T_member enthält. Ich möchte einen Standard Konstruktor schreiben (keine Argumente), der irgendwie mein T_member zu irgendeinem bekannten, Typ T spezifischen Wert initialisiert (wie -1 für Integer, Float.MAX_VALUE für Float ...). Ist das möglich? Ich habe versucht, neue T(), aber der Compiler mag das nicht. Oder mache ich nichts, und der Standardkonstruktor wird garantiert für mich aufgerufen?Java-generische Elementinitialisierung

Antwort

3

Jedes Feld in Java ohne Initialisierungsausdruck wird automatisch mit einem bekannten Standardwert initialisiert. Und ja, in diesem Fall ist es ein bekannter Wert vom Typ T - null.

+0

Ha sagte gut +1 –

3

Es ist nicht direkt möglich, da es keine Garantie gibt T sogar hat einen Standardkonstruktor. Sie könnten es jedoch mit Reflektion mit newInstance tun. Stellen Sie sicher, dass alle möglichen Ausnahmen gefunden werden.

public class MyClass<T> { 

    private T _member; 

    public MyClass(Class<T> cls) { 
     try { 
      _member = cls.newInstance(); 
     } catch (InstantiationException e) { 
      // There is no valid no-args constructor. 
     } 
    } 
} 
+0

-1 Mit 'T' können Sie nichts machen. Diese Antwort wird nicht funktionieren. Siehe meine Antwort für warum – Bohemian

+0

OMG! Du hast deine Antwort total geändert und meine Kopie über den Inhalt kopiert. Hast du keine Ehre? – Bohemian

+0

Ich habe Ihre Antwort nicht kopiert und eingefügt. Ich fügte ein Beispiel für meinen zweiten und dritten Satz hinzu. Ich habe deine Antwort aufgefrischt; hier ist kein Schaden beabsichtigt, mein Freund. –

5

Wegen type erasure, zur Laufzeit "gibt es keine T".

Der Weg darum herum ist eine Instanz von Class<T> in den Konstruktor übergeben, wie folgt aus:

public class MyClass<T> { 

    T _member; 

    public MyClass(Class<T> clazz) { 
     _member = clazz.newInstance(); // catch or throw exceptions etc 
    } 

} 

BTW, ist dies eine sehr häufige Codemuster das Thema „etwas zu tun mit T“

zu lösen
+0

Dieser Claz hat Razz-Matazz. : D Das ist ein Thema, aber ich konnte nicht widerstehen. – Wug

+3

Sie meinen * Typ * löschen, ich vertraue? (Wäre irgendwie schlecht wenn die * runtime * sich selbst gelöscht ;-) – meriton

+0

Die als Argument übergebene Klasseninstanz wird als [type token] bezeichnet (http://docs.oracle.com/javase/tutorial/extra/generics/ literals.html) – hertzsprung

0

In der Tat ist ein Weg, dies zu tun, hier ist ein Link zu answer auf verwandten SO Frage.

Also in der Tat Ihre Hauptfrage, wenn es eine Möglichkeit gibt, Klasse des generischen Mitglieds zur Laufzeit zu erhalten? Ja, da ist - mit Reflektion.

Als ich diese Antwort vor einem Jahr kam, habe ich es getestet und die Reflektion ein wenig genauer untersucht. In der Tat gab es einige Fälle, in denen es nicht wie es war (sei es bei Fällen mit Erbschaft), aber im Allgemeinen ist es falsch zu behaupten, dies sei unmöglich.

Ich jedoch stark nicht vorschlagen, tun es so.

BEARBEITEN. Überraschend fand ich meinen eigenen Kommentar unter dieser Antwort :) Und im nächsten Kommentar gibt es einen Link vom Autor zum Originalartikel über die Reflexion von Generika.