Die akzeptierte Antwort auf diese Frage beschreibt, wie eine Instanz von T
in der Generic<T>
Klasse erstellt wird. Dies beinhaltet die Übergabe eines Class<T>
Parameters an den Generic
Konstruktor und das Aufrufen der newInstance
Methode von diesem.
Generic<Bar>
Anschließend wird eine neue Instanz von erstellt und der Parameter Bar.class
übergeben.
Was tun Sie, wenn der generische Typparameter für die neue Generic
Klasse keine bekannte Klasse ist, Bar
sondern selbst ein generischer Typparameter ist? Angenommen, ich hätte eine andere KlasseSkeet<J>
und wollte eine neue Instanz Generic<J>
innerhalb dieser Klasse erstellen . Wenn ich dann versuche, weiterzugeben, J.class
erhalte ich den folgenden Compilerfehler:
cannot select from a type variable.
Gibt es einen Weg daran vorbei?
Das spezifische Codebit, das den Fehler für mich auslöst, ist:
public class InputField<W extends Component & WidgetInterface>
extends InputFieldArray<W>
{
public InputField(String labelText)
{
super(new String[] {labelText}, W.class);
}
/* ... */
}
public class InputFieldArray<W extends Component & WidgetInterface>
extends JPanel
{
/* ... */
public InputFieldArray(String[] labelText, Class<W> clazz)
throws InstantiationException, IllegalAccessException
{
/* ... */
for (int i = 0 ; i < labelText.length ; i++) {
newLabel = new JLabel(labelText[i]);
newWidget = clazz.newInstance();
/* ... */
}
/* ... */
}
/* ... */
}
Der Fehler tritt auf, weil ich nicht schreiben kann W.class
. Gibt es eine andere Möglichkeit, dieselben Informationen weiterzugeben?
Skeet<J>
richtig haben? Sie müssen diese Klasse an denGeneric
Konstruktor übergeben. Wenn Sie den tatsächlichen Code anzeigen, können wir Ihnen besser helfen.J.class
wegen Löschung des Typs nicht verwenden . Aber Sie können konkreteClass
Variable aufSkeet<J>
Bau bekommenT.class
- Sie können sie nicht.class
für Typparameter verwenden. Er meinte, einClass<T>
müsste vom Anrufer übergeben werden.J
. Ist das möglich?Antworten:
Die Verwendung
.class
auf einem Typparameter ist nicht zulässig - wegen Typ Löschung ,W
wird wurde gelöscht , umComponent
zur Laufzeit.InputField
muss auch eineClass<W>
vom Anrufer nehmen, wieInputFieldArray
:public InputField(String labelText, Class<W> clazz) { super(new String[] {labelText}, clazz); }
quelle
Object
da in diesem Fall keine Bindung angegeben ist. Da TypClass
die Unterklasse von istObject
, können wir in diesem Fall wahrscheinlich nicht aufrufen.class
. Aber was ist, wenn die angegebene Grenze nicht istObject
(<? extends Foo>
ich meine, die Methode.class
sollte in diesem Fall noch auswählbar sein. Ich bin hier ein bisschen verwirrt. @Paul Bellora.class
ist keine Methode oder etwas, das zur Laufzeit dynamisch aufgelöst werden kann. Es ist ein Konstrukt zur Kompilierungszeit, mit dem dasClass
Objekt, das einen expliziten konkreten Typ darstellt , statisch abgerufen wird .Wenn Sie die
GSON
Bibliothek verwenden, können Sie den TypT
einfach mit verwendenTypeToken
. Die Klassendokumentation finden Sie hier :Ich habe es so gemacht:
Dies ist meine Klassendefinition:
public class ManagerGeneric <T> {}
Das ist in meiner Methode:
// Get the type of generic parameter Type typeOfT = new TypeToken<T>(){}.getType(); // Deserialize T data = gson.fromJson(json, typeOfT);
quelle
W ist möglicherweise aufgrund der Löschung nicht verfügbar. Sie sollten verlangen, dass a
Class<W>
an die Methode übergeben wird. Sie erhalten ein Klassenobjekt und sein generisches Objekt stellt sicher, dassW
aufgrund der Kovarianz nur und keine Unterklasse übergeben wird.public InputField(String labelText, Class<W> cls) { super(new String[] {labelText}, cls); }
wird
W.class
aber nicht nehmenWSubtype.class
.quelle