NULL检查机制
kotlin的空安全设计对于声明可为空的参数,在使用时要做空处理判断,有两种处理方式,字段后加!!像java一样抛出空异常,另一种字段后加?可不做返回值处理为null或配合?:做空处理判断
//类型后面加?表示可为空
var age: String? = "23"
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1
当一个引用可能为 null 值时, 对应的类型声明必须明确地标记为可为 null。
当 str 中的字符串内容不是一个整数时, 返回 null:
fun parseInt(str: String): Int? {
// ...
}
以下实例演示如何使用一个返回值可为 null 的函数:
fun main(args: Array<String>) {
if (args.size < 2) {
print("Two integers expected")
return
}
val x = parseInt(args[0])
val y = parseInt(args[1])
// 直接使用 `x * y` 会导致错误, 因为它们可能为 null.
if (x != null && y != null) {
// 在进行过 null 值检查之后, x 和 y 的类型会被自动转换为非 null 变量
print(x * y)
}
}
循环控制
Break 和 Continue 标签
在 Kotlin 中任何表达式都可以用标签(label)来标记。 标签的格式为标识符后跟 @ 符号,例如:abc@、fooBar@都是有效的标签。 要为一个表达式加标签,我们只要在其前加标签即可。
loop@ for (i in 1..100) {
// ……
}
现在,我们可以用标签限制 break 或者continue:
loop@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop
}
}
类的修饰符
类的修饰符包括 classModifier 和_accessModifier_:
classModifier: 类属性修饰符,标示类本身特性。
abstract // 抽象类
final // 类不可继承,默认属性
enum // 枚举类
open // 类可继承,类默认是final的
annotation // 注解类
accessModifier: 访问权限修饰符
private // 仅在同一个文件中可见
protected // 同一个文件中或子类可见
public // 所有调用的地方都可见
internal // 同一个模块中可见
继承
Kotlin 中所有类都继承该 Any 类,它是所有类的超类,对于没有超类型声明的类是默认超类:
class Example // 从 Any 隐式继承
Any 默认提供了三个函数:
equals()
hashCode()
toString()
注意:Any 不是 java.lang.Object。
如果一个类要被继承,可以使用 open 关键字进行修饰。
open class Base(p: Int) // 定义基类
class Derived(p: Int) : Base(p)
解构声明
所谓的解构声明就是将一个对象解构(destructure)为多个变量,也就是意味着一个解构声明会一次性创建多个变量.简单的来说,一个解构声明有两个动作:
- 声明了多个变量
- 将对象的属性值赋值给相应的变量
比如,有个数据类Person,其有name和age两个属性
data class Person(var name: String, var age: Int) {
}
当我们对Person的实例使用解构声明时,可以这样做:
var person: Person = Person("Jone", 20)
var (name, age) = person
println("name: $name, age: $age")// 打印:name: Jone, age: 20
其中,”var (name, age) = person”就是解构声明,其实际意义是创建了两个变量name和age,然后将person的属性值”Jone”和20分别赋值给name和age。这是一个怎么样的一个过程呢?
在Kotlin-数据类中,我们已经了解到编译器会根据主构造器中声明的全部属性, 自动推断产生componentN() 函数群, 这些函数与类的属性对应, 函数名中的数字1到N,与属性的声明顺序一致。
解构声明在编译时将被分解为以下代码:
val name = person.component1()
val age = person.component2()
任何东西都可以作为解构声明右侧的被解构值, 只要可以对它调用足够数量的组件函数(component function). 当然, 还可以存在component3()和component4() 等等.
Parcelize
传统方法
data class Person(val name:String,val age:Int,val sex:String) :Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readInt(),
parcel.readString()) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeInt(age)
parcel.writeString(sex)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Person> {
override fun createFromParcel(parcel: Parcel): Person {
return Person(parcel)
}
override fun newArray(size: Int): Array<Person?> {
return arrayOfNulls(size)
}
}
}
@Parcelize写法
我滴妈!这也太简洁了I love it
@Parcelize
data class Person(val age : Int ,val name : String , val sex : String) : Parcelable
but 目前为止,它和Kotlin Coroutine一样也是实验性的特性,若要使用的话需要在app模块的build.gradle文件中添加下面代码:
androidExtensions {
experimental = true
}
未完待续...