特征 | Kotlin | Java |
类型推断 | 支持 | 不支持 |
空安全 | 支持 | 不支持 |
扩展函数 | 支持 | 不支持 |
Lambda 表达式 | 支持 | 不支持 |
函数式编程 | 支持 | 支持 |
数据类 | 支持 | 不支持 |
协程 | 支持 | 不支持 |
扩展属性 | 支持 | 不支持 |
集合操作 | 支持 | 支持 |
多平台开发 | 支持 | 不支持 |
可以使用 Java 库 | 支持 | 支持 |
安全性 | 更高 | 较低 |
性能 | 更快 | 较慢 |
代码量 | 更少 | 更多 |
学习难度 | 中等 | 较低 |
单个知识点学习,点击跳转详情
- 1. 变量的声明
- 2. 空安全特性
- 3. 函数的声明
- 4. 函数的默认参数
- 5. 函数的扩展
- 6. 级联调用
- 7. 类的声明
- 8. 类的继承
- 9. 类的访问修饰符
- 10. 数据类
- 11. 密封类
- 12. Lambda 表达式
- 13. 扩展函数和扩展属性
- 14. 伴生对象
- 15. 可变参数
- 16. 类型推断
- 17. 空合并运算符
- 18. Elvis 运算符
- 19. Range 表达式
- 20. Lambda 表达式的过滤器
- 21. 单例模式
- 22. when 表达式
- 23. 集合操作
- 24. 类型别名
- 25. 尾递归
- 26. 内联函数
- 27. 属性委托
- 28. lazy 初始化
- 29. 高阶函数
- 30. 函数类型
- 31. 内部类
- 32. 匿名内部类
- 33. SAM 转换
- 34. 枚举类
- 35. 局部函数
- 36. try-catch 表达式
- 37. 递归
- 38. 操作符重载
- 39. 局部变量类型推断
- 40. 协程
- 41. 延迟初始化
- 42. 懒加载
- 43. 构造函数的默认参数
- 44. 可空类型的安全调用
- 45. 非空断言
- 46. 属性引用
- 47. 函数引用
- 48. lambda 表达式的接收者
- 49. 可见性修饰符
- 50. 数据类
- 51. 密封类
- 52. 泛型协变
- 53. 泛型逆变
- 54. 泛型约束
- 55. 委托模式
- 56. 对象表达式
- 57. 对象声明
- 58. 元组
- 59. 常量
- 60. 标注注解
- Kotlin进阶
- 61. if 表达式
- 62. when 表达式
- 63. for 循环
- 64. while 循环
- 65. do-while 循环
- 66. lambda 表达式
- 67. 函数类型
- 68. 扩展函数
- 69. 中缀函数
- 70. 数据类
- 71. 密封类
- 72. 延迟初始化
- 73. 懒加载
- 74. 属性委托
- 75. 内联函数
- 76. 高阶函数
- 77. 内部类
- 78. 匿名内部类
- 79. 单例对象
- 80. 伴生对象
- 81. 反射机制
- 82. 枚举类
- 83. 操作符重载
- 84. 类型别名
- 85. 内联类
- 86. 位运算
- 87. 遍历 Map
- 88. lateinit 和 lazy 的区别
- 89. with 和 apply 函数的区别
- 90. 泛型的星号投影
- 91. 协程
- 92. withContext 函数
- 93. 协程作用域
- 94. 挂起函数
- 95. 协程取消
- 96. 协程异常处理
- 97. 协程上下文
- 98. 协程调度器
- 99. 协程 Channel
- 100. 协程 Mutex
- 101. 尾递归优化
- 102. 委托属性
- 103. 具名参数
- 104. 默认参数
- 105. 可变参数
- 106. 常量
- 107. 变量
- 108. 空安全
- 109. Elvis 运算符
- 110. 安全类型转换
- 111. 非空断言
- 112. 扩展属性
- 113. 扩展运算符
- 114. 数据类型转换
- Kotlin与Java互相转换
- 案例1
- 案例二
- 案例三 kotlin intarray 传给java的int...
以下是更多的 Java 和 Kotlin 的区别举例:
1. 变量的声明
Java:使用关键字 int
、String
等来声明变量类型,例如 int num = 10;
。
Kotlin:使用关键字 var
或 val
来声明变量,例如 var num: Int = 10
或 val name: String = "Kotlin"
。
2. 空安全特性
Java:不支持空安全特性,需要手动判断 null 值。
Kotlin:支持空安全特性,使用 ?
来标记可为空的类型,例如 var name: String? = null
。
3. 函数的声明
Java:使用关键字 void
来声明函数的返回类型,例如 public void printName(String name) {}
。
Kotlin:使用关键字 fun
来声明函数,例如 fun printName(name: String) {}
。
4. 函数的默认参数
Java:不支持函数的默认参数。
Kotlin:支持函数的默认参数,例如 fun printName(name: String, isMale: Boolean = true) {}
。
5. 函数的扩展
Java:不支持函数的扩展。
Kotlin:支持函数的扩展,例如 fun String.addHello() = this + "Hello"
。
6. 级联调用
Java:不支持级联调用。
Kotlin:支持级联调用,例如 val person = Person().apply { name = "Kotlin"; age = 20 }
。
7. 类的声明
Java:使用关键字 class
来声明类,例如 public class Person {}
。
Kotlin:使用关键字 class
来声明类,例如 class Person {}
。
8. 类的继承
Java:使用关键字 extends
来实现类的继承,例如 public class Student extends Person {}
。
Kotlin:使用关键字 :
来实现类的继承,例如 class Student : Person()
。
9. 类的访问修饰符
Java:使用关键字 public
、private
、protected
和 default
(没有修饰符)来修饰类的访问权限。
Kotlin:使用关键字 public
、private
、protected
和 internal
来修饰类的访问权限,默认为 public
。
10. 数据类
Java:不支持数据类。
Kotlin:支持数据类,使用关键字 data
来声明,例如 data class Person(val name: String, val age: Int)
。
11. 密封类
Java:不支持密封类。
Kotlin:支持密封类,使用关键字 sealed
来声明,例如 sealed class Animal {}
。
12. Lambda 表达式
Java:支持 Lambda 表达式,但写法比较繁琐。
Kotlin:支持 Lambda 表达式,写法简洁,例如 val sum = { a: Int, b: Int -> a + b }
。
13. 扩展函数和扩展属性
Java:不支持扩展函数和扩展属性。
Kotlin:支持扩展函数和扩展属性。
14. 伴生对象
Java:不支持伴生对象。
Kotlin:支持伴生对象,使用关键字 companion object
来声明,例如 companion object { fun printName() {} }
。
15. 可变参数
Java:使用 ...
来声明可变参数,例如 public void printNames(String... names) {}
。
Kotlin:使用关键字 vararg
来声明可变参数,例如 fun printNames(vararg names: String) {}
。
16. 类型推断
Java:不支持类型推断。
Kotlin:支持类型推断,例如 val num = 10
。
17. 空合并运算符
Java:不支持空合并运算符。
Kotlin:支持空合并运算符 ?:
,例如 val name = name1 ?: name2
。
18. Elvis 运算符
Java:不支持 Elvis 运算符。
Kotlin:支持 Elvis 运算符 ?:
,例如 val name = name1 ?: "Kotlin"
。
19. Range 表达式
Java:不支持 Range 表达式。
Kotlin:支持 Range 表达式,例如 val nums = 1..10
。
20. Lambda 表达式的过滤器
Java:使用 for 循环和 if 语句来实现过滤器。
Kotlin:使用 Lambda 表达式和过滤器函数来实现,例如 val nums = listOf(1, 2, 3, 4, 5).filter { it % 2 == 0 }
。
21. 单例模式
Java:使用静态变量和方法来实现单例模式,例如:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Kotlin:使用关键字 object
来实现单例模式,例如:
object Singleton {
fun printName() {
println("Kotlin")
}
}
22. when 表达式
Java:使用 if-else if-else 或 switch-case 来实现 when 表达式。
Kotlin:使用 when 表达式,例如:
when (num) {
1 -> println("One")
2 -> println("Two")
else -> println("Other")
}
23. 集合操作
Java:使用 for 循环和各种集合类的方法来实现集合操作。
Kotlin:使用 Lambda 表达式和集合操作函数来实现,例如:
val nums = listOf(1, 2, 3, 4, 5)
val sum = nums.reduce { acc, i -> acc + i }
24. 类型别名
Java:不支持类型别名。
Kotlin:支持类型别名,使用关键字 typealias
来声明,例如:
typealias Name = String
fun printName(name: Name) {}
25. 尾递归
Java:不支持尾递归。
Kotlin:支持尾递归,使用关键字 tailrec
来声明,例如:
tailrec fun factorial(n: Int, acc: Int = 1): Int {
return if (n == 1) acc else factorial(n - 1, acc * n)
}
26. 内联函数
Java:不支持内联函数。
Kotlin:支持内联函数,使用关键字 inline
来声明,例如:
inline fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
27. 属性委托
Java:不支持属性委托。
Kotlin:支持属性委托,例如:
var name: String by Delegates.observable("Kotlin") { _, old, new ->
println("$old -> $new")
}
28. lazy 初始化
Java:不支持 lazy 初始化。
Kotlin:支持 lazy 初始化,例如:
val name: String by lazy { getName() }
29. 高阶函数
Java:支持高阶函数,但写法比较繁琐。
Kotlin:支持高阶函数,写法简洁,例如:
fun process(nums: List<Int>, callback: (Int) -> Boolean) {
for (num in nums) {
if (callback(num)) {
println(num)
}
}
}
val nums = listOf(1, 2, 3, 4, 5)
process(nums) { it % 2 == 0 }
30. 函数类型
Java:不支持函数类型。
Kotlin:支持函数类型,例如:
fun interface Comparator<T> {
fun compare(o1: T, o2: T): Int
}
val nums = listOf(3, 1, 2, 5, 4)
nums.sortedWith(Comparator { o1, o2 -> o1 - o2 })
31. 内部类
Java:使用关键字 class
来声明内部类,例如:
public class Outer {
private int num = 10;
public class Inner {
public void printNum() {
System.out.println(num);
}
}
}
Kotlin:使用关键字 inner class
来声明内部类,例如:
class Outer {
private val num = 10
inner class Inner {
fun printNum() {
println(num)
}
}
}
32. 匿名内部类
Java:使用关键字 new
和接口或抽象类来创建匿名内部类,例如:
Button button = new Button();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do something
}
});
Kotlin:使用 Lambda 表达式和接口或抽象类来创建匿名内部类,例如:
val button = Button()
button.setOnClickListener {
// do something
}
33. SAM 转换
Java:不支持 SAM 转换。
Kotlin:支持 SAM 转换,例如:
interface OnClickListener {
fun onClick(view: View)
}
val button = Button()
button.setOnClickListener(object : OnClickListener {
override fun onClick(view: View) {
// do something
}
})
// 简化写法
button.setOnClickListener { view -> // do something }
34. 枚举类
Java:使用关键字 enum
来声明枚举类,例如:
public enum Color {
RED, GREEN, BLUE
}
Kotlin:使用关键字 enum class
来声明枚举类,例如:
enum class Color {
RED, GREEN, BLUE
}
35. 局部函数
Java:不支持局部函数。
Kotlin:支持局部函数,例如:
fun printName(name: String) {
fun getName(): String {
return name.toUpperCase()
}
println(getName())
}
36. try-catch 表达式
Java:使用 try-catch 语句块来捕获异常。
Kotlin:使用 try-catch 表达式来捕获异常,例如:
val result = try {
// 可能会抛出异常的代码
} catch (e: Exception) {
// 异常处理代码
""
}
37. 递归
Java:递归写法比较繁琐,容易造成栈溢出。
Kotlin:递归写法简洁,支持尾递归优化,例如:
fun factorial(n: Int): Int {
return if (n == 1) 1 else n * factorial(n - 1)
}
tailrec fun factorial(n: Int, acc: Int = 1): Int {
return if (n == 1) acc else factorial(n - 1, acc * n)
}
38. 操作符重载
Java:不支持操作符重载。
Kotlin:支持操作符重载,例如:
data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point) = Point(x + other.x, y + other.y)
}
val p1 = Point(1, 2)
val p2 = Point(3, 4)
val p3 = p1 + p2
39. 局部变量类型推断
Java:从 Java 10 开始支持局部变量类型推断,但需要使用关键字 var
。
Kotlin:默认支持局部变量类型推断,使用关键字 val
或 var
声明变量,例如:
val num = 10
var name: String? = null
40. 协程
Java:不支持协程。
Kotlin:支持协程,可以使用关键字 suspend
来声明挂起函数,例如:
suspend fun doSomething() {
delay(1000)
println("Done")
}
GlobalScope.launch { doSomething() }
41. 延迟初始化
Java:需要手动实现延迟初始化。
Kotlin:支持延迟初始化,使用关键字 lateinit
声明延迟初始化变量,例如:
lateinit var name: String
42. 懒加载
Java:需要手动实现懒加载。
Kotlin:支持懒加载,使用关键字 lazy
声明懒加载变量,例如:
val name: String by lazy { getName() }
43. 构造函数的默认参数
Java:不支持构造函数的默认参数。
Kotlin:支持构造函数的默认参数,例如:
class Person(val name: String = "Kotlin", val age: Int = 20)
44. 可空类型的安全调用
Java:不支持可空类型的安全调用。
Kotlin:支持可空类型的安全调用,使用 ?.
运算符,例如:
val nameLength = name?.length
45. 非空断言
Java:不支持非空断言。
Kotlin:支持非空断言,使用 !!
运算符,例如:
val nameLength = name!!.length
46. 属性引用
Java:不支持属性引用。
Kotlin:支持属性引用,可以使用 ::
运算符来引用属性,例如:
class Person(val name: String) {
fun printName() {
println(name)
}
}
val person = Person("Kotlin")
val nameProperty = Person::name
val name = nameProperty.get(person)
47. 函数引用
Java:不支持函数引用。
Kotlin:支持函数引用,可以使用 ::
运算符来引用函数,例如:
fun printName(name: String) {
println(name)
}
val namePrinter = ::printName
namePrinter("Kotlin")
48. lambda 表达式的接收者
Java:不支持 lambda 表达式的接收者。
Kotlin:支持 lambda 表达式的接收者,使用 with
、apply
、also
、let
、run
等函数,例如:
val person = Person("Kotlin", 20)
with(person) {
name = "Java"
age = 10
}
person.apply {
name = "Java"
age = 10
}
person.also {
it.name = "Java"
it.age = 10
}
person.let {
it.name = "Java"
it.age = 10
it
}
person.run {
name = "Java"
age = 10
this
}
49. 可见性修饰符
Java:使用关键字 public
、private
、protected
和 default
(没有修饰符)来修饰可见性。
Kotlin:使用关键字 public
、private
、protected
和 internal
来修饰可见性,默认为 public
,例如:
class Person {
public var name: String = "Kotlin"
private var age: Int = 20
protected var gender: String = "male"
internal var address: String = "Beijing"
}
50. 数据类
Java:不支持数据类。
Kotlin:支持数据类,使用关键字 data class
来声明数据类,例如:
data class Person(val name: String, val age: Int)
val person1 = Person("Kotlin", 20)
val person2 = Person("Kotlin", 20)
val person3 = person1.copy(name = "Java")
val (name, age) = person1
51. 密封类
Java:不支持密封类。
Kotlin:支持密封类,使用关键字 sealed class
来声明密封类,例如:
sealed class Shape {
data class Circle(val radius: Double) : Shape()
data class Rectangle(val width: Double, val height: Double) : Shape()
object Triangle : Shape()
}
fun getArea(shape: Shape): Double = when (shape) {
is Shape.Circle -> Math.PI * shape.radius * shape.radius
is Shape.Rectangle -> shape.width * shape.height
Shape.Triangle -> 0.0
}
52. 泛型协变
Java:支持泛型协变,但需要使用 extends
关键字。
Kotlin:支持泛型协变,使用 out
关键字来声明协变类型参数,例如:
interface List<out E> {
fun get(index: Int): E
}
53. 泛型逆变
Java:支持泛型逆变,但需要使用 super
关键字。
Kotlin:支持泛型逆变,使用 in
关键字来声明逆变类型参数,例如:
interface Comparator<in T> {
fun compare(o1: T, o2: T): Int
}
54. 泛型约束
Java:使用 extends
关键字来约束泛型类型。
Kotlin:使用 :
运算符来约束泛型类型,例如:
fun <T : Comparable<T>> maxOf(a: T, b: T): T {
return if (a > b) a else b
}
55. 委托模式
Java:需要手动实现委托模式。
Kotlin:支持委托模式,可以使用 by
关键字来实现委托,例如:
interface Printer {
fun printName(name: String)
}
class ConsolePrinter : Printer {
override fun printName(name: String) {
println(name)
}
}
class Person(val name: String, printer: Printer) : Printer by printer
val person = Person("Kotlin", ConsolePrinter())
person.printName()
56. 对象表达式
Java:不支持对象表达式。
Kotlin:支持对象表达式,使用关键字 object
来声明匿名对象,例如:
interface Printer {
fun printName(name: String)
}
val printer = object : Printer {
override fun printName(name: String) {
println(name)
}
}
printer.printName("Kotlin")
57. 对象声明
Java:不支持对象声明。
Kotlin:支持对象声明,使用关键字 object
来声明单例对象,例如:
object Singleton {
fun doSomething() {
println("Singleton")
}
}
Singleton.doSomething()
58. 元组
Java:不支持元组。
Kotlin:支持元组,使用 Pair
和 Triple
类来表示二元组和三元组,例如:
val pair = Pair("Kotlin", 20)
val triple = Triple("Kotlin", 20, "male")
val (name, age) = pair
59. 常量
Java:使用关键字 final
来声明常量。
Kotlin:使用关键字 const
(只能用于顶层和对象声明)和 val
(只读变量)来声明常量,例如:
const val PI = 3.14
val name: String = "Kotlin"
60. 标注注解
Java:不支持标注注解。
Kotlin:支持标注注解,可以在注解类上使用 @Target
注解来指定注解的作用目标,例如:
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class MyAnnotation
@MyAnnotation
class MyClass {
@MyAnnotation
fun doSomething() {
// do something
}
}
Kotlin进阶
61. if 表达式
Kotlin:if 表达式是有返回值的,可以用来赋值,例如:
val a = 10
val b = 20
val max = if (a > b) a else b
62. when 表达式
Kotlin:when 表达式类似于 switch 语句,但更加强大,例如:
fun getName(type: Int): String = when (type) {
1 -> "Kotlin"
2 -> "Java"
3 -> "Python"
else -> "Unknown"
}
63. for 循环
Kotlin:for 循环可以遍历集合、数组等对象,例如:
val list = listOf("Kotlin", "Java", "Python")
for (item in list) {
println(item)
}
64. while 循环
Kotlin:while 循环可以重复执行某个代码块,例如:
var i = 0
while (i < 10) {
println(i)
i++
}
65. do-while 循环
Kotlin:do-while 循环与 while 循环类似,但是至少会执行一次,例如:
var i = 0
do {
println(i)
i++
} while (i < 10)
66. lambda 表达式
Kotlin:lambda 表达式是一种匿名函数,可以作为参数传递给其他函数,例如:
var list = listOf(1, 2, 3, 4, 5)
list.filter { it % 2 == 0 }.forEach { println(it) }
67. 函数类型
Kotlin:函数类型是一种特殊的类型,可以作为参数或返回值使用,例如:
fun add(a: Int, b: Int) = a + b
val sum: (Int, Int) -> Int = ::add
println(sum(1, 2))
68. 扩展函数
Kotlin:扩展函数是一种将函数添加到现有类中的方式,例如:
fun String.isEmail(): Boolean {
return this.matches(Regex("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"))
}
val email = "kotlin@example.com"
println(email.isEmail())
69. 中缀函数
Kotlin:中缀函数是一种特殊的函数,可以使用中缀形式调用,例如:
infix fun String.with(other: String): String {
return "$this $other"
}
val result = "Kotlin".with("Java")
val result2 = "Kotlin" with "Java"
70. 数据类
Kotlin:数据类是一种特殊的类,可以自动生成 equals()、hashCode()、toString() 等方法,例如:
data class Person(val name: String, val age: Int)
val person1 = Person("Kotlin", 20)
val person2 = Person("Kotlin", 20)
val person3 = person1.copy(name = "Java")
val (name, age) = person1
71. 密封类
Kotlin:密封类是一种特殊的类,可以限制类的继承关系,例如:
sealed class Shape {
data class Circle(val radius: Double) : Shape()
data class Rectangle(val width: Double, val height: Double) : Shape()
object Triangle : Shape()
}
fun getArea(shape: Shape): Double = when (shape) {
is Shape.Circle -> Math.PI * shape.radius * shape.radius
is Shape.Rectangle -> shape.width * shape.height
Shape.Triangle -> 0.0
}
72. 延迟初始化
Kotlin:延迟初始化是一种将属性的初始化推迟到使用时的方式,例如:
lateinit var name: String
fun init() {
name = "Kotlin"
}
73. 懒加载
Kotlin:懒加载是一种将属性的初始化推迟到首次访问时的方式,例如:
val name: String by lazy {
println("Initializing")
"Kotlin"
}
74. 属性委托
Kotlin:属性委托是一种将属性的读写操作委托给其他对象的方式,例如:
class Example {
var p: String by Delegate()
}
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name}' in $thisRef.")
}
}
val example = Example()
example.p = "Kotlin"
println(example.p)
75. 内联函数
Kotlin:内联函数是一种将函数体直接复制到调用处的方式
76. 高阶函数
Kotlin:高阶函数是一种以函数作为参数或返回值的函数,例如:
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in this) {
if (predicate(item)) {
result.add(item)
}
}
return result
}
val list = listOf(1, 2, 3, 4, 5)
val evenList = list.filter { it % 2 == 0 }
77. 内部类
Kotlin:内部类是一种嵌套在其他类中的类,可以访问外部类的成员,例如:
class Outer {
private val name: String = "Kotlin"
inner class Inner {
fun getName(): String {
return name
}
}
}
val outer = Outer()
val inner = outer.Inner()
println(inner.getName())
78. 匿名内部类
Kotlin:匿名内部类是一种没有名字的内部类,可以直接在代码中实现一个接口或继承一个类,例如:
interface Printer {
fun printName(name: String)
}
val printer = object : Printer {
override fun printName(name: String) {
println(name)
}
}
printer.printName("Kotlin")
79. 单例对象
Kotlin:单例对象是一种只有一个实例的对象,可以使用 object
关键字来创建,例如:
object Singleton {
fun doSomething() {
println("Singleton")
}
}
Singleton.doSomething()
80. 伴生对象
Kotlin:伴生对象是一种附加在类上的单例对象,可以使用 companion object
关键字来创建,例如:
class MyClass {
companion object {
fun doSomething() {
println("Companion Object")
}
}
}
MyClass.doSomething()
81. 反射机制
Kotlin:反射机制是一种在运行时查看和修改对象的能力,例如:
class Person(val name: String, val age: Int)
val person = Person("Kotlin", 20)
val clazz = person.javaClass
val fields = clazz.declaredFields
for (field in fields) {
field.isAccessible = true
val value = field.get(person)
println("${field.name} = $value")
}
82. 枚举类
Kotlin:枚举类是一种表示一组常量的类,例如:
enum class Color {
RED, GREEN, BLUE
}
val color = Color.RED
println(color.ordinal)
83. 操作符重载
Kotlin:操作符重载是一种将操作符赋予新的含义的方式,例如:
data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}
val p1 = Point(1, 2)
val p2 = Point(3, 4)
val p3 = p1 + p2
84. 类型别名
Kotlin:类型别名是一种给类型起别名的方式,例如:
typealias MyList = List<String>
val list: MyList = listOf("Kotlin", "Java", "Python")
85. 内联类
Kotlin:内联类是一种将包装类的对象直接替换为原始类型的方式,例如:
inline class Name(val value: String)
fun getName(name: Name): String {
return name.value
}
val name = Name("Kotlin")
println(getName(name))
86. 位运算
Kotlin:位运算是一种对二进制位进行操作的方式,例如:
val a = 0b0101
val b = 0b1010
val c = a and b // 0b0000
val d = a or b // 0b1111
val e = a xor b // 0b1111
val f = a.inv() // 0b1010
87. 遍历 Map
Kotlin:遍历 Map 可以使用 for
循环,也可以使用 forEach
函数,例如:
val map = mapOf("Kotlin" to 1, "Java" to 2, "Python" to 3)
for ((key, value) in map) {
println("$key = $value")
}
map.forEach { (key, value) -> println("$key = $value") }
88. lateinit 和 lazy 的区别
Kotlin:lateinit
是一种延迟初始化方式,必须在使用前初始化,而 lazy
是一种懒加载方式,会在第一次访问时初始化。
89. with 和 apply 函数的区别
Kotlin:with
函数是一种将一个对象作为参数传递给某个函数的方式,而 apply
函数是一种在对象上执行一系列操作的方式,返回对象本身。
90. 泛型的星号投影
Kotlin:星号投影是一种忽略泛型类型参数的方式,例如:
class MyClass<T, R>
val obj1 = MyClass<String, Int>()
val obj2 = MyClass<*, Int>()
val obj3 = MyClass<String, *>()
val obj4 = MyClass<*, *>()
91. 协程
Kotlin:协程是一种轻量级的线程,使用 suspend
关键字定义挂起函数,例如:
suspend fun doSomething() {
delay(1000)
println("Done")
}
GlobalScope.launch {
doSomething()
}
92. withContext 函数
Kotlin:withContext
函数是一种在协程中切换上下文的方式,例如:
suspend fun doSomething() = withContext(Dispatchers.IO) {
// 在 IO 线程执行
}
93. 协程作用域
Kotlin:协程作用域是一种限制协程生命周期的方式,例如:
val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
// 在默认线程池中执行
}
scope.cancel()
94. 挂起函数
Kotlin:挂起函数是一种可以暂停执行的函数,可以在协程中使用,例如:
suspend fun doSomething() {
delay(1000)
println("Done")
}
GlobalScope.launch {
doSomething()
}
95. 协程取消
Kotlin:协程取消是一种终止协程执行的方式,例如:
val job = GlobalScope.launch {
while (isActive) {
// 执行任务
}
}
job.cancel()
96. 协程异常处理
Kotlin:协程异常处理是一种处理协程中抛出的异常的方式,例如:
GlobalScope.launch {
try {
// 执行任务
} catch (e: Exception) {
// 处理异常
}
}
97. 协程上下文
Kotlin:协程上下文是一种包含协程执行所需信息的对象,例如:
val context = Dispatchers.Default + CoroutineName("my-task") + CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
GlobalScope.launch(context) {
// 在默认线程池中执行
}
98. 协程调度器
Kotlin:协程调度器是一种决定协程在哪个线程或线程池中执行的方式,例如:
val context = Dispatchers.IO
GlobalScope.launch(context) {
// 在 IO 线程执行
}
99. 协程 Channel
Kotlin:协程 Channel 是一种在协程之间传递数据的方式,例如:
val channel = Channel<Int>()
GlobalScope.launch {
for (i in 1..10) {
channel.send(i)
}
channel.close()
}
GlobalScope.launch {
for (value in channel) {
println(value)
}
}
100. 协程 Mutex
Kotlin:协程 Mutex 是一种在协程之间共享锁的方式,例如:
val mutex = Mutex()
GlobalScope.launch {
mutex.withLock {
// 执行任务
}
}
101. 尾递归优化
Kotlin:尾递归是一种递归函数的特殊形式,可以通过编译器的优化避免栈溢出,例如:
tailrec fun factorial(n: Int, acc: Int = 1): Int {
return if (n == 0) acc else factorial(n - 1, acc * n)
}
val result = factorial(5)
102. 委托属性
Kotlin:委托属性是一种将属性的读写操作委托给其他对象的方式,例如:
class Person {
var name: String by Delegate()
}
class Delegate {
private var value: String = ""
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
println("getValue: ${property.name}")
return value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("setValue: ${property.name} = $value")
this.value = value
}
}
val person = Person()
person.name = "Kotlin"
println(person.name)
103. 具名参数
Kotlin:具名参数是一种通过名称来指定函数参数的方式,可以提高代码可读性,例如:
fun printPerson(name: String, age: Int) {
println("Name: $name, Age: $age")
}
printPerson(name = "Kotlin", age = 20)
104. 默认参数
Kotlin:默认参数是一种给函数参数赋默认值的方式,可以简化函数的调用,例如:
fun printPerson(name: String = "Kotlin", age: Int = 20) {
println("Name: $name, Age: $age")
}
printPerson()
printPerson(name = "Java")
printPerson(age = 30)
105. 可变参数
Kotlin:可变参数是一种接受任意数量的参数的方式,可以使用 vararg
关键字来声明,例如:
fun printPerson(vararg names: String) {
for (name in names) {
println(name)
}
}
printPerson("Kotlin", "Java", "Python")
106. 常量
Kotlin:常量是一种不可变的变量,可以使用 val
关键字来声明,例如:
val PI = 3.14159265358979323846
val URL = "https://www.example.com"
107. 变量
Kotlin:变量是一种可变的变量,可以使用 var
关键字来声明,例如:
var count = 0
count++
108. 空安全
Kotlin:空安全是一种解决空指针异常的方式,可以使用 ?
和 !!
来处理空值,例如:
var str: String? = null
str?.length // 如果 str 不为 null,返回 str 的长度,否则返回 null
str!!.length // 如果 str 不为 null,返回 str 的长度,否则抛出 NullPointerException
109. Elvis 运算符
Kotlin:Elvis 运算符是一种处理空值的方式,可以指定一个默认值,例如:
val str: String? = null
val length = str?.length ?: 0
110. 安全类型转换
Kotlin:安全类型转换是一种转换类型的方式,可以避免类型转换异常,例如:
val str: Any = "Kotlin"
val length = (str as? String)?.length ?: 0
111. 非空断言
Kotlin:非空断言是一种强制将一个变量转换为非空类型的方式,例如:
val str: String? = "Kotlin"
val length = str!!.length
112. 扩展属性
Kotlin:扩展属性是一种将属性添加到现有类中的方式,例如:
val String.isEmail: Boolean
get() = this.matches(Regex("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"))
val email = "kotlin@example.com"
println(email.isEmail)
113. 扩展运算符
Kotlin:扩展运算符是一种将数组或集合打散为参数列表的方式,例如:
fun sum(a: Int, b: Int, c: Int) = a + b + c
val list = listOf(1, 2, 3)
val result = sum(*list.toIntArray())
114. 数据类型转换
Kotlin:数据类型转换是一种将一个数据类型转换为另一个数据类型的方式,例如:
val a: Int = 10
val b: Long = a.toLong()
Kotlin与Java互相转换
案例1
TextWatcher textWatcherHumi = new TextWatcher() {
private CharSequence beforeTextChanged;
private CharSequence onTextChanged;
private boolean textChanged = false;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
beforeTextChanged = s;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
onTextChanged = s;
textChanged = true;
}
@Override
public void afterTextChanged(Editable s) {
if (textChanged) {
if (beforeTextChanged != onTextChanged) valueAnimatorHumi.start();//42.9
textChanged = false;
}
}
};
将上述代码转换为 Kotlin 代码如下:
val textWatcherHumi = object : TextWatcher {
private var beforeTextChanged: CharSequence? = null
private var onTextChanged: CharSequence? = null
private var textChanged = false
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
beforeTextChanged = s
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
onTextChanged = s
textChanged = true
}
override fun afterTextChanged(s: Editable?) {
if (textChanged) {
if (beforeTextChanged != onTextChanged) valueAnimatorHumi.start() //42.9
textChanged = false
}
}
}
在上面的 Kotlin 代码中,我们使用了对象表达式来创建一个匿名的 TextWatcher
对象,并重写了 beforeTextChanged
、onTextChanged
和 afterTextChanged
方法。
需要注意的是,在 Kotlin 中,可空类型需要使用 ?
来标识,例如 CharSequence?
、Editable?
等。此外,Kotlin 中的 if
语句可以作为表达式使用,因此可以将 if (beforeTextChanged != onTextChanged)
作为 valueAnimatorHumi.start()
的参数。
案例二
final int[] colors1 = {Color.parseColor("#FF0000"), Color.parseColor("#FFFFFF")};
将上述 Java 代码转换为 Kotlin 代码如下:
val colors1 = intArrayOf(Color.parseColor("#FF0000"), Color.parseColor("#FFFFFF"))
在上面的 Kotlin 代码中,我们使用了 intArrayOf()
方法来创建一个 Int
类型的数组,其中包含两个颜色值。由于 Kotlin 中没有 final
关键字,因此可以省略。
案例三 kotlin intarray 传给java的int…
在 Kotlin 中,使用 vararg
关键字可以将一个可变数量的参数转换为数组。因此,如果要将一个 IntArray
类型的数组传递给 Java 方法,可以使用 *
运算符将其转换为 vararg
参数。
例如,假设有一个接收 int...
参数的 Java 方法:
public static void javaMethod(int... values) {
// do something
}
那么可以将 Kotlin 中的 IntArray
类型的数组传递给该方法,示例代码如下:
val intArray = intArrayOf(1, 2, 3)
javaMethod(*intArray)
在上面的代码中,我们首先创建一个 IntArray
类型的数组 intArray
,其中包含了三个整数。然后,使用 *
运算符将该数组转换为 vararg
参数,并将其传递给 javaMethod()
方法中。
需要注意的是,*
运算符只能用于将数组转换为 vararg
参数,不能用于将单个元素转换为 vararg
参数。如果要将单个元素转换为 vararg
参数,可以使用 arrayOf()
函数将其转换为数组,然后再使用 *
运算符将其转换为 vararg
参数,示例代码如下:
val value = 1
javaMethod(*arrayOf(value))