*/
var nullableString1: String? = “abc” //?可为空, 不加?则不能为空
var nullableString2: String? = null
println(nullableString1?.length)//?.如果为空则返回null, 不为空则返回实际值
println(nullableString2?.length)
println(nullableString2?.length ?: “i am null”)//?:如果为空则用:后面的赋值
// println(nullableString2!!.length)//!!如果为空则强制抛异常
var nameNullable: String? = null
var len = nameNullable?.length
println(len == null)
/*
- 延迟初始化: lateinit var, by lazy
*/
lateinit var lateInitByLateinit: String//lateinit var只能用来修饰类属性, 不能用来修饰局部变量和基本类型
fun testLateInit() {
lateInitByLateinit = “this is a lateinit string”
}
testLateInit()
println(lateInitByLateinit)
//by lazy用来修饰val变量, 可以用来修饰局部变量和基本类型,等下一次调用到的时候才会进行初始化
val lazyByLazy: String by lazy {
println(“here is lazy init”)
“Zoo”
}
println(lazyByLazy)//lazyByLazy被调用到了,开始初始化,执行println(“here is lazy init”),并且赋值"Zoo"
/*
- is 判断类型
*/
val isString: String? = “kotlin”
if (isString is String) {
println(“it’s string”)
}
/*
- as 类型转换
*/
val y: Int? = 123;
val x: String? = y as? String;
println(x);
/*
- 方法
*/
//step1: 标准写法
fun method1(name: String): String {
return “hello $name”
}
//step2: 如果返回值类型可以由编译器推断出来,则可以省略返回值类型
fun method2(name: String) = {
“hello $name”
}
//step3: 函数只有单个表达式,则可以省略花括号,直接写在=后
fun method3(name: String) = “hello $name”
//step4: 具有代码块的函数,必须显示指明返回类型
fun method4(): Int {
println(“this is 100”)
return 100
}
println(method1(“kotlin1”))
println(method2(“kotlin2”))
println(method3(“kotlin3”))
println(method4())
//void返回类型
fun testVoid(): Unit {//Unit = java’s void
println(“this is a void fun”)
}
fun testVoidWithoutUnit() {
println(“this is a void fun without unit”)
}
fun methodWithMultipleArgs(vararg name: String) {//多个参数
println(“params size is ${name.size}”)
}
methodWithMultipleArgs(“aaron”)
methodWithMultipleArgs(“aaron”, “beyond”)
fun methodWithOneLine(age: Int): Boolean = age == 20
println(methodWithOneLine(20))
//@JvmStatic and @JvmField
println(JvmClass.name);
//方法入参可以指定默认值
fun sayHello(who: String = “Jerry”, msg: String = “Hello”) {
println(“$who - said - $msg”)
}
sayHello()
/*
9.1 Class
*/
//open表示此类可以被继承, 用在函数上面表示此函数可以被重写
open class KotlinClass(val name: String) {
open fun print(content: String?) {
println(this.name + content)
}
}
val kotlinClass = KotlinClass(“Charles”)
kotlinClass.print(" say: hello")
/*
9.2 Class extends Class and Implements interface
*/
class SubKotlinClass(name: String) : KotlinClass(name), CallBack { //父类构造函数直接赋值, 不再调用super
override fun getName(id: Int) {
println(“id = $id”)
}
override fun print(content: String?) {
println(this.name + content + “!!!”)
}
}
val subKotlinClass = SubKotlinClass(“Sub”)
subKotlinClass.print(" say: hello")
/*
9.3 Class with primary constructor, 主构造器定义在类头部, 因此需要init空间做初始化
*/
class KotlinClassConstructor1 constructor(name: String) {
val name: String
init {
this.name = name
}
}
val kotlinClassConstructor1 = KotlinClassConstructor1(“Jack”)
println(“kotlinClassConstructor:${kotlinClassConstructor1.name}”)
/*
9.4 Class with primary constructor, 主构造器定义在类头部, 也可以在类的属性初始化声明处
*/
class KotlinClassConstructor2 constructor(name: String) {
val prop: String = name.toUpperCase()
}
/*
9.5 Class with primary constructor, 如果主构造函数没有注解或可见性说明,则 constructor 关键字可以省略
*/
class KotlinClassConstructor3(name: String) {
}
/*
9.6 Class with primary constructor, 声明属性并在主构造函数中初始化更简洁的写法
*/
cl