Java-Generika (Generics) sind eine neue Funktion, die in JDK5 eingeführt wurde und die Verwendung von Typparametern (Typparameter) beim Definieren von Klassen und Schnittstellen ermöglicht. Die deklarierten Typparameter werden bei Verwendung durch bestimmte Typen ersetzt. Die wichtigste Anwendung von Generika liegt jetzt im neuen Collection-Klassen-Framework in JDK5, wo Map und List verwendet werden. Die Vorteile liegen auf der Hand. Wir können mehr Klassen horizontal erweitern, denn wenn wir generische Klassen verwenden, müssen wir uns über den Zweck unseres Codes im Klaren sein und dürfen keine Fehler verwenden.
Die grundlegendste generische Klasse
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e1;
/**
* Die grundlegendste generische Klasse, der Typ wird von Ihnen selbst definiert
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Point<T> {
private T-Variable;
öffentliches T getVar() {
return var;
}
public void setVar(T var) {
this.var = var;
}
}
Paket com.garinzhang.javabase.generic.e1;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Point<String> p = new Point<String> ();
p.setVar("coder");
System.out.println(p.getVar());
}
}
Mehrere generische Typen
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e2;
/**
* Im Allgemeinen ist es am besten, Buchstaben in der Nähe von T zu verwenden, z. B. S, R usw.
* @Autor Garin Zhang
*
* @param <T>
* @param <S>
*/
öffentliche Klasse Notepad<T, S> {
privater T-Schlüssel;
privater S-Wert;
öffentliches T getKey() {
return this.key;
}
public S getValue() {
return this.value;
}
public void setKey(T key) {
this.key = Schlüssel;
}
public void setValue(S value) {
this.value = value;
}
}
Paket com.garinzhang.javabase.generic.e2;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Notepad<String, Integer> p = new Notepad<String, Integer> ();
p.setKey("coder");
p.setValue(99999);
System.out.println("key: " + p.getKey());
System.out.println("value: " + p.getValue());
}
}
Verwenden Sie den Platzhalter „?“ in Methodenparametern
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e3;
/**
* Der Schlüssel zu diesem Beispiel liegt in der Hauptmethode
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Info<T> {
privater T-Schlüssel;
öffentliches T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = Schlüssel;
}
@Override
öffentlicher String toString() {
return this.key.toString();
}
}
Paket com.garinzhang.javabase.generic.e3;
/**
* Verwenden Sie Platzhalter in Methodenparametern
* @Autor Garin Zhang
*
*/
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i = new Info<String>();
i.setKey("coder");
Spaß(i);
Info<Integer> j = new Info<Integer>();
j.setKey(9999);
Spaß(j);
}
public static void fun(Info<?> temp) {
System.out.println("Content: " + temp);
}
}
Die Aufwärtstransformation scheitert
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e4;
/**
* Der Schlüssel zu diesem Beispiel liegt in der Hauptmethode
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Info<T> {
privater T-Schlüssel;
öffentliches T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = Schlüssel;
}
@Override
öffentlicher String toString() {
return this.key.toString();
}
}
Paket com.garinzhang.javabase.generic.e4;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
Info<Object> objEg;
// Kompilierungsfehler „Typkonflikt: Konvertierung von Info<String> in Info<Object> nicht möglich“
//Upcast fehlgeschlagen, String -> Objekt
// objEg = strEg;
}
}
Die Verwendung von Generika in Schnittstellen
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e5;
/**
* Der Schlüssel zu diesem Beispiel liegt in der Hauptmethode
* @Autor Garin Zhang
*
* @param <T>
*/
Schnittstelle Info<T> {
öffentliches T getVar();
}
Paket com.garinzhang.javabase.generic.e5;
/**
* Generische Klasse
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse InfoImpl<T> implementiert Info<T> {
private T-Variable;
public InfoImpl(T var) {
this.setVar(var);
}
public void setVar(T var) {
this.var = var;
}
öffentliches T getVar() {
return this.var;
}
}
Paket com.garinzhang.javabase.generic.e5;
/**
* Nicht generische Klasse
* @Autor Garin Zhang
*
* @param <T>
*/
Die öffentliche Klasse InfoImpl1 implementiert Info<String> {
private String var;
public InfoImpl1(String var) {
this.setVar(var);
}
public void setVar(String var) {
this.var = var;
}
öffentlicher String getVar() {
return this.var;
}
}
Paket com.garinzhang.javabase.generic.e5;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new InfoImpl<String>("coder");
System.out.println("Content: " + strEg.getVar());
Info<String> strEg1 = new InfoImpl1("coder1");
System.out.println("Content: " + strEg1.getVar());
}
}
Platzhalter und die Verwendung von Extends und Super
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e6;
/**
* Der Schlüssel zu diesem Beispiel liegt in der Hauptmethode
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Info<T> {
privater T-Schlüssel;
öffentliches T getKey() {
return this.key;
}
public void setKey(T key) {
this.key = Schlüssel;
}
@Override
öffentlicher String toString() {
return this.key.toString();
}
}
Paket com.garinzhang.javabase.generic.e6;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
strEg.setKey("coder");
//Kompilierungsfehler „Die Methode fun(Info<? erweitert Number>) im Typ GenericExample ist für die Argumente (Info<String>) nicht anwendbar“
// upTypeLimit(i);
// Verwenden Sie die Typen „Ganzzahl“ oder „Zahl“.
Info<Integer> intEg = new Info<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
//Kompilierungsfehler „Die Methode downTypeLimit(Info<? super String>) im Typ GenericExample ist für die Argumente (Info<Integer>) nicht anwendbar“
// downTypeLimit(intEg);
// Da super verwendet wird, kann downTypeLimit nur String selbst und Object empfangen
// Überprüfe die Vererbungsbeziehung von String. Es werden keine anderen Klassen vererbt, nur Object
downTypeLimit(strEg);
Info<Object> objEg = new Info<Object>();
objEg.setKey(999);
downTypeLimit(objEg);
}
/**
* <? erweitert T> stellt die Obergrenze des Typs dar und gibt an, dass der parametrisierte Typ T oder eine Unterklasse von T sein kann
* @param temp
*/
public static void upTypeLimit(Info<? erweitert Number> temp) {
System.out.println("Content: " + temp);
}
/**
* <? super T> stellt die untere Typgrenze dar (in Java Core als Supertypqualifizierung bezeichnet) und gibt an, dass der parametrisierte Typ der Supertyp (übergeordneter Typ) dieses Typs ist, bis Object
* In diesem Beispiel bedeutet dies, dass T nur Object oder String sein kann, da String nur von Object erbt
* @param temp
*/
public static void downTypeLimit(Info<? super String> temp) {
System.out.println("Content: " + temp);
}
}
Methodengenerika, mehrere Generika in der Methode
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e7;
/**
* Methodengenerika, mehrere Generika in der Methode
* @Autor Garin Zhang
*
* @param <T>
*/
Informationen zur öffentlichen Klasse {
/**
* Format: Methodenänderung <durch Kommas getrennte Typliste> Rückgabewerttyp Methodenname (Parameterliste)
* Zum Beispiel: public <T, S> T fun(T t, S s)
* @param t
* @param s
* @zurückkehren
*/
public <T, S> T fun(T t, S s) {
System.out.println(s.toString());
Rückkehr t;
}
}
Paket com.garinzhang.javabase.generic.e7;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info info = neue Info();
String str = info.fun("coder", "print second generic param");
System.out.println(str);
int i = info.fun(30, "zweiten Parameter erneut drucken");
System.out.println(i);
}
}
Der in der Methode übergebene oder zurückgegebene generische Typ wird durch den beim Aufruf der Methode festgelegten Parametertyp bestimmt.
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e8;
/**
* erstreckt sich
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Info<T erweitert Number> {
private T-Variable;
öffentliches T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
öffentlicher String toString() {
return this.var.toString();
}
}
Paket com.garinzhang.javabase.generic.e8;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<Integer> intEg = fun(30); // Der Typ hier wurde als Integer festgelegt
System.out.println(intEg.getVar());
}
/**
* Der in der Methode übergebene oder zurückgegebene generische Typ wird durch den beim Aufruf der Methode festgelegten Parametertyp bestimmt.
* @param param
* @zurückkehren
*/
public static <T erweitert Number> Info<T> fun(T param) {
Info<T> temp = new Info<T>();
temp.setVar(param);
Rücklauftemperatur;
}
}
Machen Sie die beiden in der Methode übergebenen Parametertypen konsistent
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e9;
/**
* Hauptansicht
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Info<T> {
private T-Variable;
öffentliches T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
@Override
öffentlicher String toString() {
return this.var.toString();
}
}
Paket com.garinzhang.javabase.generic.e9;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i1 = new Info<String>();
i1.setVar("Hallo");
Info<String> i2 = new Info<String>();
i2.setVar("Coder");
Info<Integer> i3 = new Info<Integer>();
i3.setVar(999);
add(i1, i2);
//Kompilierungsfehler „Die Methode add(Info<T>, Info<T>) im Typ GenericExample ist für die Argumente (Info<String>, Info<Integer>) nicht anwendbar“
// add(i1, i3);
}
/**
* Die beiden in der Methode übergebenen Parametertypen müssen konsistent sein
* @param param
* @zurückkehren
*/
public static <T> void add(Info<T> i1, Info<T> i2) {
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}
Generics, variable Parameter, ähnlich dem Arguments-Objekt in JavaScript
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e10;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Ganzzahl i[] = fun(1, 2, 3, 4, 5, 6);
fun2(i);
}
public static <T> T[] fun(T... arg) {
return arg;
}
public static <T> void fun2(T param[]) {
System.out.println("generisches Array: ");
for(T t : param) {
System.out.println(t + " ,");
}
}
}
Generische Verschachtelung: Verwenden Sie generische Klassen als Parameter. Bestimmen Sie den Rückgabewert basierend auf dem Rückgabewerttyp
Kopieren Sie den Codecode wie folgt:
Paket com.garinzhang.javabase.generic.e11;
/**
* Akzeptiert zwei generische Typen
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Info<T, V> {
private T-Variable;
privater V-Wert;
öffentliches T getVar() {
return this.var;
}
public void setVar(T var) {
this.var = var;
}
public V getValue(){
return this.value;
}
public void setValue(V value) {
this.value = value;
}
@Override
öffentlicher String toString() {
return this.var.toString();
}
}
Paket com.garinzhang.javabase.generic.e11;
/**
* Akzeptiert 1 generischen Typ
* @Autor Garin Zhang
*
* @param <T>
*/
öffentliche Klasse Demo<S> {
private S-Info;
öffentliche Demo(S-Info) {
this.setInfo(info);
}
public void setInfo(S info) {
this.info = info;
}
public S getInfo() {
gib this.info zurück;
}
}
Paket com.garinzhang.javabase.generic.e11;
java.util.List importieren;
import com.google.common.collect.Lists;
öffentliche Klasse GenericExample {
/**
* @param args
*/
public static void main(String[] args) {
Demo<Info<String, Integer>> d;
Info<String, Integer> i;
i = new Info<String, Integer>();
i.setVar("Coder");
i.setValue(999);
d = new Demo<Info<String,Integer>>(i);
System.out.println("Content: " + d.getInfo().getVar());
System.out.println("Content: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5]
// Warnung „Typsicherheit: Ein generisches Array von Object&Comparable<?>&Serializable wird für einen varargs-Parameter erstellt“
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("I", "am", "a", "coder").toString());// [I , am , a , coder]
List<String> list = Lists.newArrayList("I", "am", "a", "coder");
System.out.println(list.toString()); // [I , am , a , coder]
}
/**
* Bestimmen Sie den generischen Typ über den Rückgabewert. Der Rückgabewerttyp in dieser Methode wird automatisch durch die Definition der Methode generiert.
* @param-Elemente
* @zurückkehren
*/
öffentliche statische <E> List<E> query(E... elements) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
//import com.google.common.collect.Lists;
// <Abhängigkeit>
// <groupId>com.google.guava</groupId>
// <artifactId>Guave</artifactId>
// <version>16.0.1</version>
// </dependency>
return Lists.newArrayList(elements);
}
}