Kotlin入门(三)——变量与问号

来源:互联网 发布:51单片机下载器 编辑:程序博客网 时间:2024/06/04 23:35

参考

        官网链接。

问号?

        定义变量时,可在类型后面加一个问号?,表示该变量是Nullable,不加表示该变量不可为null。如下:

var s:String? = nullvar s2:String = "xxx" //如果该变量被赋值为null,则编译不通过
        从其对应的java文件(从编译成的class文件中反编译出来的)截取两个变量的setter方法如下:

        从中可以看出,在为变量s设置值的时候,是直接赋值的;而为变量s2赋值的时候,首先进行了非空判断,这保证了s2不可能为null。

        对于可以为null的变量,在使用该变量的时候,必须用变量名+?(如上面的s?)的形式进行调用,表示如果该变量为null,则不执行该变量调用的方法。如:

s = "yyy"//赋值时不需要使用s?形式var l= s?.length//如果s为null,则不执行length方法
        当s为null时,不会执行length方法,从而避免了java中频繁的空指针异常。

var与val

        所有成员变量(包括定义在类中,以及直接定义在kt文件中的)在定义时必须进行初始化,局部变量(定义在方法内)可以不进行初始化。如:
var s:String? = nullvar s2:String = ""fun main(args:Array<String>){var t:Test = Test()var m:Int//可以不进行初始化}class Test{var test:String = ""}
        上述代码中s,s2,test三个变量必须进行初始化,而非 m却不需要。

        var:定义可变变量。

        val:定义常量,定义的变量是final类型的。如Kotlin源码为:

var a:Int = 2val b = 1

        反编译其class文件如下,从中可以看出b是final类型的,而a是可变的:


getter与setter

        一个变量的完整定义形式如下:

var <propertyName>[: <PropertyType>] [= <property_initializer>]    [<getter>]    [<setter>]

        var类型的变量才能定义setter,val代表常量,不能定义setter方法。<>是必写项,[]是选填。

        对于变量类型(PropertyName),如果可以通过初始值推断出或者通过getter方法的返回值推断出来,则可以省略不写,否则必须写。

        通过get()或set()定义getter或setter,并使用field表示当前的变量。对于默认的getter与setter实现,可以不进行定义,除非要在getter或setter中进行更多的操作。如下:

fun main(args:Array<String>){val d = Demo()d.test="this is from test"//会调用setter方法println(d.test)//会调用getter方法}class Demo{var test="haha"get():String{//通过get()指定当前定义的是getterprintln("call getter")return field //通过field代替该变量,不能直接写成变量名test}set(value:String){//通过setter指定当前定义的是setter,value的类型可以省略println("call setter")field = value//也是通过field代表变量,不能写成变量名test}}

        对于set方法,其参数类型必须是变量的类型。比如上面的test是String类型的,那么set()的参数必须是String类型的,不能设置成Int等别的类型。

        对于getter,如果是单语句函数,也可以进行简写。如下:

class Demo{var test="haha"get()= field //getter只返回字段值,因此可以简写set(value){//setter是没办法简写的,因为它set(value) = field = value编译报错field = value}}

        虽然上面setter方法的变量名用的是value,但这并不是固定死的,可以随意换。

        也可以通过private关键词对getter或setter进行修饰,改变这些方法的可见性,如下:

fun main(args:Array<String>){var t = Demo()t.test ="test private"//此句会编译不通过,因为它的setter方法是privateprintln(t.test)}class Demo{var test="haha"get()= fieldprivate set //将setter方法定义为private类型}

field

        在getter与setter中,使用field代表当前的变量,不能直接使用变量名。如下:

class Demo{var test="haha"get()= field //这里不能直接返回test,否则会无限调用,直到报java.lang.StackOverflowError。}
        要注意的是:field标识符只能用于getter与setter中,不能用在别的地方。

        另外,只有当使用到field字段或者getter,setter中有一个默认实现时,才有field字段。别的时候并没该字段。









































原创粉丝点击