这篇文章首先会介绍Kotlin的特点,接着介绍Kotlin与Java的语法比较。
下面进入Kotlin的语法部分。
;
结尾 println()
代替 System.out.println();
$变量名
代替Java中的 +变量名
,比如 println("age:$age")
而不是 System.out.println("age:"+age)
var
声明变量 val
声明常量 var
/ val
后面加上类型,比如 val a:Int
如上图提示 val
不能被赋值,提示改为 var
。 val
类似与Java中的 final
,虽然 val
引用自身不可变,但是指向的对象是可以改变的。
val
只能进行唯一一次初始化,如果编译器能确保只有唯一一条初始化语句被执行,可以根据条件进行不同的初始化操作:
val a:Int if (4>3) { a = 9 } else { a = 10 }
Java中所有的控制结构都是语句,在Kotlin中除了三大循环( while
, for
, do while
)外,大多数控制结构都是表达式。比如 if
是表达式而不是语句。也就是说, if
有值而不像Java里面一样没有值(语句)。
例子:
var a = if (3>2) 3 else 2
fun main() { var a = max(4,9) } fun max(a:Int,b:Int): Int = if(a>b) a else b
使用 enum class
而不是Java中的 enum
:
fun main() { val months = Months.May println(months.days) } enum class Months(val days:Int) { May(31), Jun(30) }
when
相当于Java中的 switch
:
fun main() { val months = Months.May when(months) { Months.May -> print("May") Months.Jun -> print("June") } } enum class Months(val days:Int) { May(31), Jun(30),; }
使用 ->
进行了简化。
与Java一样。
使用 ..
表示区间,在 i
前面没有类型:
for (i in 1..100) print(i)
注意区间是两边都包含的,也就是 1..100
表示 i
从1循环到100。
使用下标迭代:
val arr = arrayListOf("1111","2222","333") for ((i,e) in arr.withIndex()) println("$i = $e")
输出:
0 = 1111 1 = 2222 2 = 333
class Person(val name:String)
不需要像Java一样 this.xxx=xxx
。
因为 val
代表常量,而 var
代表变量,setter是用于改变值的,因此,使用 var
声明的属性具有getter与setter,使用 val
声明的属性只有getter。
Kotlin没有提供直接操纵getter与setter的方式,通过使用 .属性名
进行修改属性或者获取属性:
class Person { var name = "" val id = "" } var person = Person() person.name="111" person.id="222" //编译不通过,id为val不可变
在相应的属性后面加上 get
/ set
即可自定义getter/setter:
class Person { var name="" get() { return "name"+field } var id="" set(id) { field = id } }
在 get
/ set
中使用 field
表示字段,比如在上面例子中的get中, field
表示 name
,而在下面的 set
中, field
表示自己的 id
, =
后面是参数的 id
。
直接 throw
,无需 new
:
val age = 300 if(age !in 1..100) throw IllegalArgumentException("Out of range:$age")
try { throw Exception("exception") } catch (e:Exception) { e.printStackTrace() }
Java中的异常有两类:
Unchecked Exception
:不受检异常,可以不进行 try/catch
处理,包括 Runtime Exception
及其子类 Checked Exception
:受检异常,必须进行 try/catch
处理或者声明需要抛出,不属于不受检异常的异常都属于受检异常 Kotlin不区分两者,也就是对于Java的受检异常可以不处理,比如:
fun main() { throw IllegalArgumentException("333") }
可通过编译,而Java中的
public class Test { public static void main(String []args) { throw new Exception("111"); } }
则无法通过编译。
val arrayList = ArrayList<Int>() arrayList.add(3) arrayList.add(9) arrayList.forEach { t-> println(t) } val hashSet = hashSetOf<String>() hashSet.add("2222") hashSet.add("99999") hashSet.forEach{t-> println(t)} val list = listOf(3,5,5) list.forEach{t-> println(t)} val map = mapOf("a" to 1,"b" to 2) map.forEach{(k,v)-> println("$k to $v")}
可以直接使用集合类或者 xxxOf
创建,遍历使用 forEach
与Lambda,Kotlin风格的Lambda使用 {}
。
fun printStr(str:String) { println(str) } fun add(a:Int):Int { return a+3 }
fun :
Java里面没有默认参数,实现类似功能需要重载去解决,而Kotlin的函数可以具有默认参数:
fun main() { println(add()) println(add(1)) println(add(1,2)) } fun add(a:Int = 3,b:Int = 4):Int = a+b
可以省略的只有在末尾的参数,也就是默认参数从末尾开始确定默认值。
类似Python,调用函数时使用形参名称与值的方式调用而不是仅仅通过值调用,同时可以结合默认参数省略部分值。
fun main() { println(add(b=1)) println(add(b=5,a=9)) } fun add(a:Int = 3,b:Int = 4):Int = a+b
使用 vararg
:
fun main() { println(add(1,2,3,4)) } fun add(vararg a:Int):Int = a.sum()
Kotlin中可以将函数放在代码文件的顶层,不用附属于任何类,但仍然是包内作用域,包外需要 import
,作用类似Java中的静态函数。
fun add(vararg a:Int):Int = a.sum() fun main() { println(add(1,2,3,4)) }
Java中调用顶层函数时可以使用默认的Kotlin文件名作为默认包去调用,也可以使用 @file:JvmName
修改调用的包名,比如上面的文件名为 Test.kt
,则Java中调用的代码如下:
TestKt.add()
使用注解后:
@file:JvmName("Test") fun add(vararg a:Int):Int = a.sum fun main() { println(add(1,2,3,4)) }
Java调用方式改变如下:
Test.add()
与Java中的静态属性类似,有点像全局变量或全局常量,可以使用 var
, val
, const val
修饰:
var a = 0 val b = 0 const val c = 0 fun main() { println(++a) println("$b/n$c") test() } fun test() { println("$a/n$b/n$c") }
val
与 const val
的主要区别是:
val
实质上相当与Java中的 private final static
const val
实质上相当于Java中的 public final static
const
相当于 @JvmField
,也就是说 const val a = 0
与 @JvmField val a = 0
等价: 1、 Kotlin语言的特点和优劣势
2、 Java受检异常与不受检异常
3、 Kotlin中的getter与setter
4、 Kotlin与Java的异同
5、 Kotlin之const val与val