Android

Kotlin基础

2019-04-22  本文已影响2人  Merbng

简介

Kotlin虽然说是Java的扩展,能进行混合调用,但是在语法规则上完全不同于java,所以学习的时候要么直接忘了java语法,要么比较一下看看区别在哪,这里我选择前者。

关键字

open override fun inline inner internal data companion object lateinit var val

when in is

and or

类型

Boolean Byte Short Int Long Float Double Char

语法

这里说个小技巧,可以使用AS自带的Java代码转换成Kotlin文件,菜单栏的 code ->Conver Java File to Kotlin File

在Kotlin中 常量用val声明,变量用var声明,关键字在前面,类型以冒号:隔开在后面,也可以直接省略赋值,类型后带?表示可为空类型(默认空安全),常量val延迟加载by lazy{},默认线程安全,关闭线程安全lazy(LazyThreadSafetyMode.NONE){},变量var延迟加载lateinit

条件

if...else 正常使用,不过移除了switch,用更加强大的when替代。when子式可以是任何返回Boolean的表达式。


val x= 1

when(x){

  in 1..10 ->print("x is in the range")

  in validNumbers ->print("x is valid")

  !in 10...20 ->print("x is outside the range")

  else -> print(" none of the above")

}

循环

whiledo..while 跟Java并无区别,for 则有很大变化并多出了几个变种


val list =ArrayList<String>()



//递增for(int i;i<list.size();i++){}

for(i in list.indices){

  print(list[i])

}



//递增for(int i=2;i<list.size();i++){}

for(i in 2..list.size-1){

  print(list[i])

}



//递减 for(int i =list.size();i>=0;i--){}

for(i in list.size downTo 0){

  print(list[i])

}



//操作列表内的对象

for(item in list){

print(item)

}



//加强版

for((i,item) in list.withIndex()){

  print(list[i])

  print(item)

}



//变种版

list.forEach{

  print(it)

}



list.forEachIndexed{i,s->

  print(list[i])

  print(s)

}



list.forEachIndexed(object : (Int,String) -> Unit{

  override fun invoke(i : Int , s : String){

  print(list[i])

  print(s)

}

})

属性

kotlin中的属性可以用var声明为可变的,也可以用val声明为只读的。


class Demo {

var name : String = "this is name"

var age : Int = 0

var detail : String?

}

要使用一个属性,只要用名称引用即可


class Demo2(name : String) : Demo{

  val demo = Demo();//创建对象

  var name =demo.name

  var age : Int  = demo.age

}

3.幕后字段

kotlin中类不可以有字段,但是可以使用自定义访问器时,kotlin提供了一个自动幕后字段,通过field访问,

field幕后字段只可以在自定义访问器中使用


var a =12 //初始值会直接赋值给幕后字段field

get(){

  //直接引用field做判断

return if(field >=0) field else -field

}

set(value){

  //使用传入的值做判断

  if(value >100){

    println("赋值大于100,默认的field还为&field")

  }else{

    field =value

    println("赋值成功,&field")

  }

}

4.幕后属性

通过默认getter setter访问私有属性会被优化,不会引入函数调用开销


private var _map : Map<String,Int>? =null

public val map: Map<String,Int>

  get(){

  if(_map ==null){

    _map= HashMap()//类型推断

  }

  return _map?:throw AssertionError("Set to null by another thread")

  }

5.延迟初始化属性与变量

一般情况下,属性声明为非空类型必须在构造函数中初始化,然而,属性可以通过依赖注入初始化,或者可以通过单元测试settu()初始化

这种情况下,不能在构造函数中提供非空的初始化器,又想在引用时避免空检查就可以使用lateinit延迟初始化属性和变量。


class Person{

  lateinit var name :String

  //通过setup方法或者注解等初始化

  @Setup fun setUp(){

    name =''tim"

  }

  @Test

  fun show(){

    print(name)//因为name是String非空类型,所以此时调用就避免了空检查,打印tim

  }

}

注意:

1.lateinit 只能用于类体中的属性,不能是主构造函数中的属性,也不能有自定义访问器getter setter

2.kotlin1.2之后,可以用于顶层属性和局部变量

3.该属性必须是非空类型,不能是原生类型

4.该属性初始化之前访问,会抛出UninitializedPropertyAccessException



6.检测一个lateinit var 是否已经初始化

Kotlin1.2之后 可以 检测一个lateinit var 是否已经初始化,只需要在该属性的引用上使用.isInitialized


class Person {

  lateinit var name :String

  fun show(){

  if(::name.isInitialized){

    print(name)

  }else{

    print("name 还未初始化")

  }

}

}

参考资料:

上一篇 下一篇

猜你喜欢

热点阅读