Heim  >  Artikel  >  Java  >  Generische Platzhalter und begrenzte Typparameter in Java

Generische Platzhalter und begrenzte Typparameter in Java

php是最好的语言
php是最好的语言Original
2018-08-06 16:55:421401Durchsuche

Typ-Platzhalter

Typ-Platzhalter werden im Allgemeinen anstelle spezifischer tatsächlicher Typparameter verwendet (Hier handelt es sich um tatsächliche Typparameter, nicht um formale Typparameter) . Wenn Sie beim Betrieb eines Typs nicht die spezifischen Funktionen des Typs verwenden müssen, sondern nur die Funktionen in der Object-Klasse, können Sie das Platzhalterzeichen ? verwenden, um unbekannte Typen darzustellen. Beispielsweise ist List6b3d0130bba23ae47fe2b8e8cddf0195 logischerweise die übergeordnete Klasse aller tatsächlichen Parameter vom Typ Listf7e83be87db5cd2d9a8a0b8117b38cd4 usw.

public class GenericTest {    
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();   
        name.add("zwj");
        age.add(18);
        number.add(120);
   
        getNumberData(age); // 报错
        getNumberData(number); // 120
        getData(name);  // zwj
        getData(age); // 18
        getData(number); // 120
        //getUperNumber(name); // 出现错误,方法中的参数已经限定了参数泛型上限为Number
        getUperNumber(age); //18
        getUperNumber(number); //120       
    }
    /**
     * 在使用List<Number>作为形参的方法中,不能使用List<Ingeter>的实例传入,
     * 也就是说不能把List<Integer>看作为List<Number>的子类;
     */
    public static void getNumberData(List<Number> data) {
        System.out.println("data :" + data.get(0));
    }
    /**
     * 使用类型通配符可以表示同时是List<Integer>和List<Number>的引用类型。
     * 类型通配符一般是使用?代替具体的类型实参,注意此处是类型实参;
     * 和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类。
     */
    public static void getData(List<?> data) {
        System.out.println("data :" + data.get(0));
    }
    /**
     * 类型通配符上限通过形如List来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。
     */
    public static void getUperNumber(List<? extends Number> data) {
          System.out.println("data :" + data.get(0));
    }
}

Begrenzte Typparameter

Manchmal möchten wir den Bereich der Typen einschränken, die an einen Typparameter übergeben werden dürfen. Beispielsweise möchte eine Methode, die mit Zahlen arbeitet, möglicherweise nur Instanzen von Number oder eine Unterklasse von Number akzeptieren. Zu diesem Zeitpunkt muss Monkey dem Generikum eine Obergrenze hinzufügen, dh das übergebene Typargument muss ein Subtyp des angegebenen Typs sein.

Um einen begrenzten Typparameter zu deklarieren, listen Sie zunächst den Namen des Typparameters auf, gefolgt vom Schlüsselwort „extends“ oder „super“ und schließlich gefolgt von seiner Ober- oder Untergrenze. Daraus können wir erkennen, dass die Addition der oberen und unteren Grenzen eines Generikums zusammen mit der Deklaration des Generikums erfolgen muss.

71b63f436d94a50f17c5ed897161f1dd gibt an, dass der durch den Platzhalter dargestellte Typ eine Unterklasse des T-Typs ist. Wenn Sie beispielsweise Elemente zu einer Sammlung hinzufügen, können Sie entweder ein E-Typ-Objekt oder ein E-Subtyp-Objekt hinzufügen. Warum? Denn beim Abrufen kann der E-Typ sowohl E-Klassenobjekte als auch E-Subtypobjekte empfangen.

117c5a0bdb71ea9a9d0c2b99b03abe3e bedeutet, dass der durch den Platzhalter dargestellte Typ die übergeordnete Klasse des Typs T ist. Wenn Sie beispielsweise Elemente aus einer Sammlung für den Betrieb abrufen, können Sie den Typ des aktuellen Elements zum Empfangen oder den übergeordneten Typ des aktuellen Elements zum Empfangen verwenden.

public class GenericMethodTest {
    // 比较三个值并返回最大值
    public static <T extends Comparable<T>> T getMaxNuum(T x, T y, T z) {                     
        T max = x; // 假设x是初始最大值
        if ( y.compareTo( max ) > 0 ){
            max = y; //y 更大
        }
        if ( z.compareTo( max ) > 0 ){
            max = z; // 现在 z 更大           
        }
        return max; // 返回最大对象
    }
    public static void main( String args[] ) {
        System.out.println( "结果 " + getMaxNuum(3, 4, 5) );  // 结果 5
        System.out.println( "结果 " + getMaxNuum(1.2, 6.6, 10.10) ); // 结果 10.10
   }
}

Wir können auch die vorherige Definition der generischen Klasse ändern:

public class GenericClassDemo<T extends Number> { 
    private T t;   
    public GenericClassDemo() { 
    }
    public GenericClassDemo(T t) { 
        this.t = t;
    }
    public void setT(T t) {
        this.t = t;
    }
    public T getT(){ 
        return t;
    }
}

Zu diesem Zeitpunkt kann beim Instanziieren der generischen Klasse GenericClassDemo der Parametertyp nur Number und Number-Unterklassen sein. Schauen wir uns auf dieser Grundlage ein Beispiel einer generischen Methode an:

/**
 * 在泛型方法中添加上下边界限制的时候, 必须在泛型声明的时候添加;
 * 也就是在权限修饰符与返回值之间的<T>上添加上下边界
 */
public <T extends Number> T getT(GeneriClassDemo<T> demo){
    T t = demo.getT();
    return t;
}

Generisches Array

In Java können Sie kein Array eines exakten generischen Typs erstellen .

List<String>[] lsa = new ArrayList<String>[10];  // Not really allowed. 
Object o = lsa;    
Object[] oa = (Object[]) o;    
List<Integer> li = new ArrayList<Integer>();    
li.add(new Integer(3));    
oa[1] = li; // Unsound, but passes run time store check    
String s = lsa[1].get(0); // Run-time error: ClassCastException.

In diesem Fall kennt die JVM aufgrund des generischen Löschmechanismus der JVM die generischen Informationen zur Laufzeit nicht, sodass Sie oa[1] ausnahmslos eine ArrayList zuweisen können. Beim Abrufen von Daten gilt jedoch: Eine Typkonvertierung ist erforderlich, sodass eine ClassCastException auftritt. Wenn ein generisches Array deklariert werden kann, führt die obige Situation nur dann zu Warnungen oder Fehlern, wenn die Kompilierung ausgeführt wird. Wenn Sie die Deklaration generischer Arrays einschränken, werden Sie in solchen Fällen möglicherweise zur Kompilierzeit darauf hingewiesen, dass der Code Probleme mit der Typsicherheit aufweist, was viel besser ist, als überhaupt keine Eingabeaufforderung zu geben.

Die folgenden Wildcard-Methoden sind zulässig:

Der Typ des Arrays darf keine Typvariable sein, es sei denn, die Wildcard-Methode wird verwendet, da für die Wildcard-Methode die endgültigen Daten extrahiert werden müssen Explizite Typkonvertierung.

List<?>[] lsa = new List<?>[10]; // OK, array of unbounded wildcard type.    
Object o = lsa;    
Object[] oa = (Object[]) o;    
List<Integer> li = new ArrayList<Integer>();    
li.add(new Integer(3));    
oa[1] = li; // Correct.    
Integer i = (Integer) lsa[1].get(0); // OK

Verwandte Artikel:

Der Unterschied zwischen T und Fragezeichen (Platzhalter) in Java-Generika

Generika in Java Ausführliche Erklärung des Typs

Das obige ist der detaillierte Inhalt vonGenerische Platzhalter und begrenzte Typparameter in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn