Heim >Java >JavaBase >Lassen Sie uns über die Kovarianz und Kontravarianz von Kotlin aus Java sprechen
Lassen Sie uns über die Kovarianz und Kontravarianz von Kotlin aus Java sprechen
coldplay.xixinach vorne
2020-10-13 11:14:232068Durchsuche
Java Basic TutorialIn der heutigen Spalte werden Kovarianz und Kontravarianz in Kotlin vorgestellt.
Vorwort
Um Kovarianz und Kontravarianz in Kotlin und Java besser zu verstehen, werfen wir zunächst einen Blick auf einige Grundkenntnisse.
Normale Zuweisung
In Java lauten die üblichen Zuweisungsanweisungen wie folgt:
A a = b;复制代码
Die Bedingungen, die die Zuweisungsanweisung erfüllen muss, sind: Die linke Seite ist entweder die übergeordnete Klasse der rechten Seite oder vom gleichen Typ wie die rechte Seite Seite. Das heißt, der Typ von A muss „größer“ sein als der Typ von B, wie zum Beispiel Object o = new String("s"); . Der Einfachheit halber wird es im Folgenden als A > Object o = new String("s"); 。为了方便起见,下文中称作 A > B。
除了上述最常见的赋值语句,还有两种其他的赋值语句:
函数参数的赋值
public void fun(A a) {}// 调用处赋值B b = new B();
fun(b);复制代码
在调用 fun(b) 方法时,会将传入的 B b 实参赋值给形参 A a,即 A a = b 的形式。同样的,必须要满足形参类型大于实参,即 A > B。
函数返回值的赋值
public A fun() {
B b = new B(); return b;
}
复制代码
函数返回值类型接收实际返回类型的值,实际返回类型 B b 相当于赋值给了函数返回值类型 A a,即 B b 赋值给了 A a, 即 A a = b,那么必须满足 A > B 的类型关系。
所以,无论哪种赋值,都必须满足左边类型 > 右边类型,即 A > B。
Java 中的协变与逆变
有了前面的基础知识,就可以方便地解释协变与逆变了。
如果类 A > 类 B,经过一个变化 trans 后得到的 trans(A) 与 trans(B) 依旧满足 trans(A) > trans(B),那么称为协变。
逆变则刚好相反,如果类 A > 类 B,经过一个变化 trans 后得到的 trans(A) 与 trans(B) 满足 trans(B) > trans(A),称为逆变。
但是很抱歉,由于种种原因,Java 并不支持。但是,Java 并不是完全抹杀了泛型的型变特性,Java 提供了 extends T> 和 super T> 使泛型拥有协变和逆变的特性。
extends T> 与 super T>
extends T> 称为上界通配符, super T> 称为下界通配符。使用上界通配符可以使泛型协变,而使用下界通配符可以使泛型逆变。
比如之前举的例子
List<Integer> l = new ArrayList<>();
List<Object> o = l;// 这里会报错,不能编译复制代码
如果使用上界通配符,
List<Integer> l = new ArrayList<>();
List<? extends Object> o = l;// 可以通过编译复制代码
这样,List extends Object> 的类型就大于 List 的类型了,也就实现了协变。这也就是所谓的“子类的泛型是泛型的子类”。
同样,下界通配符 super T> 可以实现逆变,如:
public List<? super Integer> fun(){
List<Object> l = new ArrayList<>(); return l;
}复制代码
上述代码怎么就实现逆变了呢?首先,Object > Integer;另外,从前言我们知道,函数返回值类型必须大于实际返回值类型,在这里就是 List super Integer> > List<object></object>
Zusätzlich zu den oben genannten häufigsten Zuweisungsanweisungen gibt es zwei weitere Zuweisungsanweisungen:
Zuweisung von Funktionsparametern
public class Container<T> { private T item; public void set(T t) {
item = t;
} public T get() { return item;
}
}复制代码
🎜Beim Aufruf der fun(b)-Methode wird it will Der übergebene Aktualparameter B b wird dem formalen Parameter A a zugewiesen, also in der Form A a = b. Ebenso muss der formale Parametertyp größer als der tatsächliche Parameter sein, d. h. A > 🎜
Zuweisung des Funktionsrückgabewerts🎜
Container<Object> c = new Container<String>(); // (1)编译报错Container<? extends Object> c = new Container<String>(); // (2)编译通过c.set("sss"); // (3)编译报错Object o = c.get();// (4)编译通过复制代码
🎜Der Funktionsrückgabewerttyp empfängt den Wert des tatsächlichen Rückgabetyps. Der tatsächliche Rückgabetyp B b entspricht der Zuweisung des Funktionsrückgabewerttyps A a, also B b, wird A a zugewiesen, also A a = b, dann muss die Typbeziehung von A > erfüllt sein. 🎜🎜Egal um welche Art von Aufgabe es sich handelt, sie muss den linken Typ > erfüllen. 🎜
Kovarianz und Kontravarianz in Java🎜🎜Mit den bisherigen Grundkenntnissen lassen sich Kovarianz und Kontravarianz leicht erklären. 🎜🎜Wenn Klasse A > Klasse B, trans(A) und trans(B), die nach einer Änderung von trans erhalten werden, immer noch trans(A) > erfüllen, dann werden sie als kovariante bezeichnet . 🎜🎜Inverse Variation ist genau das Gegenteil. Die nach einer Änderung erhaltenen trans(A) und trans(B) erfüllen trans(B) > inverse Änderung. 🎜🎜Jeder weiß zum Beispiel, dass Java-Arrays kovariant sind, dann kann A[] > Zum Beispiel: 🎜
Container<String> c = new Container<Object>(); // (1)编译报错Container<? super String> c = new Container<Object>(); // (2)编译通过
c.set("sss");// (3) 编译通过
String s = c.get();// (4) 编译报错复制代码
🎜Aber Javas Generika erfüllen die Kovarianz nicht, wie folgt: 🎜
public class Container<T> { private T item; public void set(T t) {
item = t;
} public T get() { return item;
}
}复制代码
🎜Der obige Code meldet einen Fehler, da die Generika trotz Objekt > Ganzzahl nicht die Kovarianz erfüllen, also List
Das obige ist der detaillierte Inhalt vonLassen Sie uns über die Kovarianz und Kontravarianz von Kotlin aus Java sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!