Kotlin基础
简介
Kotlin虽然说是Java的扩展,能进行混合调用,但是在语法规则上完全不同于java,所以学习的时候要么直接忘了java语法,要么比较一下看看区别在哪,这里我选择前者。
关键字
-
by
as
lazy
init
downTo
-
声明
open
override
fun
inline
inner
internal
data
companion
object
lateinit
var
val
- 判断
when
in
is
- 运算
and
or
类型
-
Any
Unit
-
基本类型:
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")
}
循环
while
和 do..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
}
-
Getter Setter
1.声明一个属性的完整语法:
var 属性名: 属性类型 = 初始化器 getter方法 setter方法 其中初始化器,getter,setter方法都是可选的,如果属性的返回值类型可 以用初始化器或者getter方法中推断出来,则可以省略, var allByDefault : Int? //错误,需要显示初始化器,隐含默认getter和setter var age =20 // 类型 int , 默认getter,setter方法
2.自定义getter,setter方法
var stringResponding : String get() =this .toString() set(value){ setDataFormString(value) //解析字符串并赋值给其他属性 }
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 还未初始化")
}
}
}
参考资料: