Heim  >  Artikel  >  Java  >  Welche Auswirkungen hat die Typschutzfunktion von Generika in Java auf den Code?

Welche Auswirkungen hat die Typschutzfunktion von Generika in Java auf den Code?

WBOY
WBOYnach vorne
2023-04-26 13:34:081203Durchsuche

Verwenden Sie Generika, um Typunterschiede abzuschirmen

In der C++-Sprache gibt es eine sehr nützliche Vorlagenfunktion, die eine allgemeine Version mit parametrisierten Typen schreiben kann, sodass der Compiler automatisch spezifische Versionen für verschiedene Typen generieren kann. In der Java-Sprache gibt es eine ähnliche Funktion namens Generics. Beim Schreiben von Klassen und Methoden werden im Allgemeinen bestimmte Typen verwendet, und Generika können zum Parametrisieren von Typen verwendet werden, sodass allgemeinerer Code geschrieben werden kann.

Viele Leute glauben, dass die Konzepte von C++-Vorlagen und Java-Generika gleichwertig sind, aber tatsächlich sind die Implementierungsmechanismen völlig unterschiedlich. C++-Vorlagen sind eine Reihe von Makroanweisungen, und der Compiler erstellt eine Kopie des Vorlagencodes für jeden Typ. Die Implementierung von Java-Generika basiert auf dem Konzept der „Typlöschung“, bei dem es sich im Wesentlichen um einen syntaktischen Zucker für Typbeschränkungen handelt.

1. Generische Klasse

Nehmen Sie die unterstützende Klasse des Generikums:

/** 通用支撑类 */@Getter@Setter@ToStringpublic class GenericHolder<T> {    /** 通用取值 */
    private T value;    /** 构造函数 */
    public GenericHolder() {}    /** 构造函数 */
    public GenericHolder(T value) {        this.value = value;
    }
}

2. Definieren Sie die generische Datenanbieterschnittstelle:

/** 数据提供者接口 */public interface DataProvider<T> {    /** 获取数据函数 */
    public T getData();
}

Definieren Sie eine generische flache Kopierfunktion:

/** 浅拷贝函数 */public static <T> T shallowCopy(Object source, Class<T> clazz) throws BeansException {    // 判断源对象
    if (Objects.isNull(source)) {        return null;
    }    // 新建目标对象
    T target;    try {
        target = clazz.newInstance();
    } catch (Exception e) {        throw new BeansException("新建类实例异常", e);
    }    // 拷贝对象属性
    BeanUtils.copyProperties(source, target);    // 返回目标对象
    return target;
}

Generische Platzhalter verwenden im Allgemeinen „?“ anstelle von tatsächlichen Parametern eines bestimmten Typs. Wenn der spezifische Typ unsicher ist, können Sie den generischen Platzhalter „?“ verwenden. Wenn Sie die spezifischen Funktionen des Typs nicht verwenden müssen und nur die Funktionen in der Object-Klasse verwenden, können Sie den generischen Platzhalter „?“ verwenden.

/** 打印取值函数 */public static void printValue(GenericHolder<?> holder) {
    System.out.println(holder.getValue());
}/** 主函数 */public static void main(String[] args) {
    printValue(new GenericHolder<>(12345));
    printValue(new GenericHolder<>("abcde"));
}
In der Java-Spezifikation wird die Verwendung des generischen Platzhalters „?“ nicht empfohlen. Die obige Funktion kann geändert werden in:

/** 打印取值函数 */public static <T> void printValue(GenericHolder<T> holder) {
    System.out.println(holder.getValue());
}

5. Bei Verwendung von Generika können wir auch die festlegen Eingehende generische Typ-Aktualparameter unterliegen Ober- und Untergrenzen. Beispielsweise dürfen Typ-Aktualparameter nur in einem bestimmten Typ einer übergeordneten Klasse oder einem bestimmten Typ einer Unterklasse übergeben werden. Die Deklaration der oberen und unteren Grenzen eines generischen Typs muss zusammen mit der Deklaration des generischen Typs erfolgen.

Platzhalter für obere Grenze (erweitert):

Der Platzhalter für obere Grenze ist „erweitert“, der seinen angegebenen Typ oder seine Unterklasse als allgemeinen Parameter akzeptieren kann. Es gibt auch eine spezielle Form, die angibt, dass es sich nicht nur um eine Unterklasse des angegebenen Typs handeln muss, sondern auch bestimmte Schnittstellen implementieren muss. Beispiel: List gibt an, dass es sich um eine Liste einer bestimmten Unterklasse von A handelt und das gespeicherte Objekt A oder eine Unterklasse von A sein muss. Für die Liste „Liste“ können Sie kein A oder ein Unterklassenobjekt von A hinzufügen, sondern nur das Objekt von A abrufen.

Platzhalter für untere Grenze (super):

Der Platzhalter für untere Grenze ist „super“, der seinen angegebenen Typ oder seine übergeordnete Klasse als allgemeinen Parameter akzeptieren kann. Beispiel: List gibt an, dass es sich um eine Liste einer bestimmten übergeordneten Klasse von A handelt und das gespeicherte Objekt A oder eine Oberklasse von A sein muss. Für List können Sie A oder ein Unterklassenobjekt von A hinzufügen, aber Sie können nur das Objekt von Object abrufen.

PECS-Prinzip (Producer Extends Consumer Super):

Beim Bereitstellen von Daten als Produzent (Auslesen) ist es sinnvoll, Obergrenzen-Wildcards zu verwenden (erweitert);

Beim Konsumieren von Daten als Konsument (Einschreiben) ist es sinnvoll um untere Grenzen zu verwenden Wildcard (super).

Bei der täglichen Codierung wird häufiger der Platzhalter für die Obergrenze (erweitert) verwendet, der zum Begrenzen der übergeordneten Klasse eines generischen Typs verwendet wird. Der Beispielcode lautet wie folgt:

/** 数字支撑类 */@Getter@Setter@ToStringpublic class NumberHolder<T extends Number> {    /** 通用取值 */
    private T value;    /** 构造函数 */
    public NumberHolder() {}    /** 构造函数 */
    public NumberHolder(T value) {        this.value = value;
    }
}/** 打印取值函数 */public static <T extends Number> void printValue(GenericHolder<T> holder) {
    System.out.println(holder.getValue());
}

Das obige ist der detaillierte Inhalt vonWelche Auswirkungen hat die Typschutzfunktion von Generika in Java auf den Code?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen