Basics
kotlin中一切皆对象,基本数据类型会自动装箱成对象
基本数据类型位宽与java一致
数组处理
java中基本数据类型的数组用于避免封箱开箱的操作,在kotlin中每一个java基本类型的数组都有与其对应的类型IntArray DoubleArray....
它们不是Array类,而是被编译成java的原生数组,来获得最好的性能
其for-each 及 in check也不会带来额外的开销(都转换成java基本类型操作)
如果java定义变长基本类型时,kotlin需传递类似*IntArray给java
kotlin中无受检异常
也就是说,编译器不会强制你去捕捉任何异常
位操作
shl 类似 <<
shr >>
ushr >>>
and &
or |
xor ^
inv ~
布尔运算
布尔值的相关运算与java类似 || && !
Array
//Array支持lambda参数的构造函数
var a:Array = Array(2, {it->it*2});
String
支持字符串模板,原生字符串(like python)
Import
支持import as
Visibility Control
- private 当前类可见
- protected private + 继承类可见
- internal 同一模块可见(模块一般指intellij中的一个module)
- public 全部可见
Class and Objects
Constructor
class Person private constructor(name:String) {
// 基础构造函数不能放初始化代码,如需,放init中
init {
var s = name.length
}
consturtor(parent:Person) {
// 如果有基础构造函数,必须调用
this(parent.name)
}
}
// 如果不声明任何构造函数,会自动获得一个(类似java)
Inheritance
open class Derived(p:Int):Base(p) { // 继承
// 构造函数必须显示调用父类
consturtor(ctx:Int):super(ctx) {
}
}
默认情况下所有类都是final的除非声明为open,默认所有的方法也是final的
支持多继承
Object
object 用于声明单例对象,object声明不能有构造函数
object Instance {
val name = ""
}
Companion Objects
kotlin没有静态成员,但有伴随对象,这样类似静态成员的效果
open class A {
companion object {
val DEF_NAME = "DefaultName";
}
open fun test() {
}
}
Properties
var : [= ] []
[]
自定义setter的时候,如果需要对变量赋值,可以使用Backing Field
eg :
open class Test {
var a : String? = null
set(value) {
if (!value.isNullOrBlank()) {
field = value // 此处如果使用a=value会导致递归调用
}
}
}
编译期常量使用const 字段修饰
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
可使用lateinit关键字进行懒加载(主要用于单元测试 setUp初始化)
如果定义一些属性并且使用基本构造函数初始化的话一种简练的写法是
class Test(var/val name:String)
Interface
接口类似java8 可以有方法实现,但其properties必须是abstract
Extensions
Extensions are resolved statically
扩展方法是静态解析的,也就是说根据对象的声明类型而不是实际类型来解析应该调用哪个扩展方法的
支持扩展属性,但必须通过get set访问,无法直接初始化
伴随对象也支持扩展
class C {
fun D.foo() { // D的扩展函数
toString() // calls D.toString()
[email protected]() // calls C.toString()
}
Generics
由于kotlin也是jvm语言,因此无法规避java泛型相关问题,仍遵循 PECS (Producer-Extends, Consumer-Super),不过增加了in out关键字,变成了 Consummer in, Producer out
对于java中
fun cloneWhenGreater(list: List, threshold: T):Listwhere T : Comparable,T : Cloneable {
return list.filter { it > threshold }.map { it.clone()
}
}
Nested Classes
声明普通内部类需使用 inner关键字否则的话就类似java的静态内部类
枚举类声明为 enum class XXX
Delegated Properties
代理属性
代理属性在被访问的时候会调用代理对象的相关方法
object Instance {
var age:String by Delegate()
}
class Delegate {
operator fun getValue(any: Instance, property: KProperty<*>): String {
return any.age
}
operator fun setValue(instance: Instance, property: KProperty<*>, s: String) {
print("you set $instance's age = $s")
}
}