Bitte erklären Sie das benutzerdefinierte 'T' in der Java-Oberfläche. Es verwendet hier Generika und vom Typ 'T' nehme ich an. Wo ist dann der Typ "T" definiert?Custom Generics Erklärung
public interface TemplateBuilder<T extends TemplateBuilder>
Bitte erklären Sie das benutzerdefinierte 'T' in der Java-Oberfläche. Es verwendet hier Generika und vom Typ 'T' nehme ich an. Wo ist dann der Typ "T" definiert?Custom Generics Erklärung
public interface TemplateBuilder<T extends TemplateBuilder>
T ist keine tatsächliche Klasse. Es wird zur Kompilierzeit abhängig von der Verwendung Ihrer Klasse TemplateBuilder bestimmt. Stellen Sie sich einfach einen Platzhalter für verschiedene mögliche Typen vor, von denen einer abhängig von Ihren Umständen ausgewählt wird.
Für ein einfacheres Beispiel, Blick auf die folgenden (aus Java Tutorial angepasst):
Stellen Sie eine Klasse Box deklarieren möchten, die einen bestimmten Typ (des Objekts in der Box zu halten) nehmen, aber Sie möchten dies unter verschiedenen Umständen wiederverwenden, um verschiedene Typen zu halten.
Anstatt also die tatsächliche Art der Befestigung der Box nehmen, erklären Sie es wie folgt:
public class Box<T> {
private T t; // T stands for "Type"
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
Wenn Sie es verwenden, können Sie dann so etwas wie:
Box<Integer> integerBox = new Box<Integer>();
Was ist die ganze Punkt, den Sie fragen könnten? Warum macht Box nicht ein Objekt?
Tatsächlich war dies vor Java 1.5 nicht möglich. Dies wurde eingeführt, um in diesen Situationen eine weitere Typensicherheit zu erreichen, und wurde im Rahmen der Sammlung eingeführt.
Der springende Punkt ist, dass ohne diesen Mechanismus, wenn stattdessen Object verwendet wurde, Sie eine bestimmte Instanz Ihrer Box nicht zwingen können, nur ganze Zahlen zu speichern. Wenn Sie andererseits die Verwendung von Ganzzahlen explizit festgelegt haben, können Sie Ihre Box für String oder andere Objekte nicht wiederverwenden, und Sie müssten eine andere Art von Box-Klasse erstellen.
Vor Java 1.5 haben Objekte wie ArrayList einfache Objekte übernommen, jedoch gab es oft Fälle von Typensicherheit zur Laufzeit, da das Programm eine Liste von Integer-Objekten annimmt und versehentlich irgendwo einen String eingefügt wird. Generika (durch dieses magische T) zwingen Typen, ohne einzuschränken, was sie sein könnten.
In Ihrem Fall T extends TemplateBuilder
geht einen Schritt weiter und besagt, dass was auch immer T ist, muss es eine Klasse sein, die TemplateBuilder erweitert. Wenn dies nicht der Fall wäre, würde jede Klasse Object (die universelle Basisklasse von Java) erweitern.
T ist eine beliebige, die Object
T bedeutet ein beliebiges Objekt von TemplateBuilder
erstreckt. zum Beispiel
List<T> list = new ArrayList<T>();
hier kann T Integer
, String
... sein
und <T extends A>
bedeutet jede Object T
von A
erstreckt Dieser Typ wird definiert, wenn die Schnittstelle implementiert, dh
class StringBuilder implements TemplateBuilder<StringBuilder> {}
BTW, siehe Klasse Enum (die Basisklasse aller Enums).
My Custom Generics Erklärung
Backgorund:
Beispiel
Als Beispiel betrachten die folgenden zwei Klassen, unter dem nicht verwandten sind. Dies ist ein sehr einfaches Beispiel gibt aber dennoch einen Überblick über die Prinzipien des benutzerdefinierten Generika:
/**
*
* Class A is a Custom Generic class that can be 'typed'
* to any kind of class using diamond 'T' syntax.
*
*/
class A<T>
{
// The instance variable of the object type 'T' known at run time
T theI;
// The constructor passing the object type 'T'
A(T anI)
{
this.theI = anI;
}
// Method to return the object 'T'
T getT()
{
return theI;
}
}
Unten ist die Klasse B, die A dh B erstreckt sich nicht A-Klasse nicht in Beziehung steht:
/**
*
* Simple class which overrides the toString()
* method from Object's class toString() method
*
*/
class B
{
@Override
public String toString()
{
return "B Object";
}
public static void main(String[] args)
{
A<B> a = new A<>(new B());
System.out.println(a.getT());
}
}
In Hauptmethode der Klasse B oben:
a.getT() gibt das Objekt 'T' zurück, das in diesem Beispiel vom Typ 'B' ist (Dies ist ein Beispiel für Polymorphie).
a.getT() gibt das Objekt 'T' zurück, die Methode der Objektinstanz C toString() wird IMPLICITLY aufgerufen, da sie die toString() - Methode von Object überschreibt und "B Object" ausgibt.
Der interessante Aspekt über Custom Generics und Polymorphismus zu beachten ist, dass:
Im Rahmen von kundenspezifischen Generika gibt es keine Einschränkungen für eine Beziehung zwischen den Klassen, um Polymorphismus
auszuführen z.B. Klasse B ist unabhängige bis A oben d.h Klasse B erstreckt sich nicht A.
In „traditionellen“ objektorientierte Polymorphismus Prinzipien, gibt es immer eine Anforderung Einschränkung für Klassen in irgendeiner Weise zusammenhängen. Dies ist jedoch in benutzerdefinierten Generika nicht erforderlich.2
Beispiel
public interface TemplateBuilder<T extends TemplateBuilder>
Das obige bedeutet, dass TemplateBuilder Schnittstelle sein kann zu jeder Klasse typisiert dass TemplateBuilder erstreckt.
Nehmen wir an, Someclass TemplateBuilder erstreckt sich dann die folgende ist in Ordnung:
TemplateBuilder<SomeClass> tbRef = ...
/* Using an Anonymous Inner Class reference to interface TemplateBuilder<SomeClass> */
oder
TemplateBuilder<SomeClass> tbRef = .... /* Referencing a concrete class
that implements TemplateBuilder */
Ist 'einen Typ oder einen Tippfehler IntegerBox'? – HyperNeutrino
Ja ... fest ... Prost. – jbx