基础语法
在线简单kotlin例子测试网站
1.函数
带有两个 Int 参数、返回 Int 的函数
fun sum(a: Int, b: Int): Int {
return a + b
}
将表达式作为函数体、返回值类型自动推断的函数:
fun sum(a: Int, b: Int) = a + b
函数返回无意义的值:
fun printSum(a: Int, b: Int): Unit { //Unit 也可以省略不写
println("sum of $a and $b is ${a + b}")
}
2.构造方法
1.实例化代码不需要new变量和常量
3.变量和常量
1.变量(var) 可重新赋值的变量
kotlin 编译器可以自动推断出变量的类型,通常不需要指定变量的类型
private var index: Int = 0 //定义具体的类型
private var a = 0 //自动识别是int类型,通常不需要指定变量的类型
private var point: Point? = null //定义对象在这里插入代码片
//使用的时候,因为point是可空的,所以有两种用法
println(point?.x) //如果你不能确保point是否为空
println(point!!.x) //如果你能确保point一定不为空,否则point为空,这里会报运行时空指针
fun main() {
var point= Point(20,"DASD")
println("这是=${point.x}") //如果你不能确保point是否为空
println("这是=${point!!.y}") //如果你能确保point一定不为空,否则point为空,这里会报运行时空指针
//使用的时候,因为point是可空的,所以有两种用法
}
class Point( x:Int, y:String){
val x=x
val y=y
}
这是=20
这是=DASD
使用lateinit var,可以使得变量的初始化可以延迟到需要的时候
比如在使用dagger的时候,需要inject,如下
@Inject lateinit var mPresenter: MapHomePresent
但是需要慎用lateinit, 因为你可能后面忘记了初始化,但是编译器又不会报错提醒。只有运行之后才会检测到,如下
fun main(args: Array<String>) {
var test = Test()
//test.a="dada" 增加初始化
println(test.a)
}
class Test {
lateinit var a: String
}
Exception in thread “main” kotlin.UninitializedPropertyAccessException:
lateinit property a has not been initialized
2.常量(val) 只能为其赋值一次。
通常不需要指定变量的类型, kotlin 中有一个重要的概念是:尽可能地使用 val。
val s = "String" //类型为String
val ll = 22L //类型为Long
val d = 2.5 //类型为Double
val f = 5.5F //类型为Float
val point = Point(20, 20) //类型为Point对象
point一定不会为空,因为val定义的变量必须要初始化,避免了人为导致的空指针错误
不定义类型而导致产生编译时错误:point = Point(30, 30)
需要注意的是,point不能被修改,但是Point类里面的成员变量是可修改的,所以下面操作是允许
point.x = 30
point.y = 30
4.与java的类似
对于基本类型,Kotlin 相比 Java 有几点特殊的地方
数字、字符和布尔值可以在运行时表示为原生类型值,但对开发者来说,它们看起来就像普通的类
Kotlin 对于数字没有隐式拓宽转换,而在 Java 中 int 可以隐式转换为 long
在 Kotlin 中字符不能视为数字
Kotlin 不支持八进制
val intIndex: Int = 100
//等价于
//val intIndex = 100,编译器会自动进行类型推导
//数字类型不会自动转型,必须要进行明确的类型转换
val doubleIndex: Double = intIndex.toDouble()
//以下代码会提示错误,需要进行明确的类型转换
//val doubleIndex: Double = intIndex
//Char 不能直接作为数字来处理,需要主动转换
val ch: Char = 'c'
val charValue: Int = ch.toInt()
//以下代码会提示错误
//val charValue: Int = ch
//二进制
val value1 = 0b00101
//十六进制
val value2 = 0x123
此外,Kotlin 的可空类型不能用 Java 的基本数据类型表示,因为 null 只能被存储在 Java 的引用类型的变量中,这意味着只要使用了基本数据类型的可空版本,它就会被编译成对应的包装类型
5. Any 和 Any?
Any 类型是 Kotlin 所有非空类型的超类型
如果把基本数据类型的值赋给 Any 类型的变量,则会自动装箱
val any: Any = 100
println(any.javaClass) //class java.lang.Integer
如果想要使变量可以存储包括 null 在内的所有可能的值,则需要使用 Any?
val any: Any? = null
6. ?. 和 !!. 和 ?= 和 ?: 的含义
?= 操作符,当前面的值不为空取前面的值,否则取后面的值,这和java中三目运算符类似
!!. 操作符可以跳过限制检查通过编译,此时如果变量为空会抛出空指针异常。
a!!.foo()
//相当于java:
if(a!=null){
a.foo();
}else{
throw new KotlinNullPointException();
}
?. 操作符,就先判空,如果不为空则赋值
a?.foo()
//相当于java:
if(a!=null){
a.foo();
}
?: 的意思是,左边的表达式没有成功,则使用右边的结果;如下,bannerBean是null,所以bannerBean?.title不会执行,所以最终a == “null”
var bannerBean : BannerBean? = null
var a = bannerBean?.title ?: "null"
得到a==‘“null”
7. 修饰符
public,private,protected
internal:如果是一个定义为 internal 的包成员的话,对所在的整个 module 可见。如果它是一个其它领域的成员,它就需要依赖那个领域的可见性了。比如,如果我们写了一个 private 类,那么它的 internal 修饰的函数的可见性就会限制于它所在的这个类的可见性。 我们可以访问同一个 module 中的 internal 修饰的类,但是不能访问其它 module 的
final和oepn
Kotlin 中的类和方法默认都是 final 的,即不可继承的,如果想允许创建一个类的子类,需要使用 open 修饰符来标识这个类,此外,也需要为每一个希望被重写的属性和方法添加 open 修饰符
final和oepn
Kotlin 中的类和方法默认都是 final 的,即不可继承的,如果想允许创建一个类的子类,需要使用 open 修饰符来标识这个类,此外,也需要为每一个希望被重写的属性和方法添加 open 修饰符
8. 运算符重载
一元操作符
操作符 | 函数 |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
a++ | a.inc() |
aa– | a.dec() |
一元操作符
操作符 | 函数 |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a…b | a.rangeTo(b) |
a in b | b.contains(a) |
a !in b | !b.contains(a) |
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
a %= b | a.remAssign(b) |
学习资料来源于他们分享日志
–杨充大佬的学习总结
–kotlin 语言中文站