Java和Kotlin中的变异
我一直对Java的泛型很感兴趣,想在自己的脑海中简单总结一下我所调查的内容。此外,我还想与我最近喜爱的语言Kotlin进行比较。因为我仍然是一个学习中的人,所以如果有错误,请谅解。
永恒不变
必须是相同的类型。
Java
Java 作为一种编程语言,在软件开发中具有广泛的应用。它是一种可移植、跨平台的编程语言,被广泛用于开发各种应用程序和互联网应用。Java具有简单易学、面向对象、可靠性高等优点,被称为一种通用的编程语言。不仅如此,Java还有一个庞大的开发社区,提供了丰富的开发工具和资源,使得开发人员能够更加高效地开发出高质量的应用程序。
Note: The provided translation is in simplified Chinese.
在Java中,不变性是指List。
List<String> strList = new ArrayList<String>();
List<Object> objList = strList; //コンパイルエラー 不変のため代入できない
在Java中,数组是协变的。
Kotlin 哈哈
与Java不同,这是一个数组。
此外,Kotlin可以使用listOf,arrayListOf和mutableListOf来创建Java中的列表。
//配列
val intArray: Array<Int> = arrayOf(1,2)
val numArray: Array<Any?> = intArray //コンパイルエラー 共変ではないため
//リスト
val strList: java.util.ArrayList<String> = arrayListOf("1st", "2nd")
顺便提一下,我定义了一个 Array 类型,但在 Kotlin 中似乎还可以为每种类型准备数组。
val intArray: IntArray = intArrayOf(3,4)
共変 可以被解释为物体或系统在变化过程中彼此保持相对关系的性质。
可以将狭义的事物纳入到广义的定义中。
Java
Java 语言
在Java中,我们可以通过数组和带有上限边界的通配符来实现协变。
由于String类型是Object类型的子类,可以分别按以下方式来表示。
//配列
String[] strArray = {"hoge", "foo"};
Object[] objArray = strArray;
//上限付き境界ワイルドカード
List<String> strList = new ArrayList<String>();
List<? extends Object> objList = strList;
无法存储不同类型的对象。
objArray[0] = 1; //ランタイムエラー
在String类型的数组中,即使放入其他类型的元素也能通过编译,但在运行时会产生错误。
而在列表中,无论是String类型还是Object类型,都不能使用add方法添加元素,但可以使用get方法获取String类型或Object类型的元素。
(可以添加null元素)。
Kotlin(科特林)
在Kotlin中,使用out修饰符实现了协变。与Java的数组不同的是,它只允许输出,从而可以安全地处理。
val intArray: Array<Int> = arrayOf(1,2)
val numArray: Array<out Any?> = intArray
numArray[0] = 1 //コンパイルエラー
逆变
它的反义词是反变。
Java – Java
在Java中,协变有下界限定通配符。由于Object类型拥有String类型的子类,因此可以按照以下方式编写。
//下限付き境界ワイルドカード
List<Object> objList = new ArrayList<Object>();
List<? super String> strList = objList;
通过下限限制,可以通过add方法添加String类型及其子类。还可以添加null。
相反,在get方法中只能获取Object类型,它是所有超类的类型。
Kotlin → Kotlin是一种编程语言
在Kotlin中,通过”in”修饰符实现了逆变。
与协变相反,”in”修饰符只允许输入,不允许输出。
fun main(args: Array<String>) {
var hoge = Hoge(1)
val hogeList: java.util.ArrayList<Hoge> = arrayListOf(hoge)
val fooList: java.util.ArrayList<in Foo> = hogeList //反変だから代入できる
val foo = fooList[0]
println(hoge == foo) // true
println(hoge.a) //1が出力される
println(foo.a) //コンパイルエラー
}
open class Hoge(val a: Int)
class Foo: Hoge(0)