前言
首先,现在来写这篇文章,我很惭愧。去年5月份的Google I/O 大会上,Google宣布 Kotlin成为Android 开发的1级编程语言,而我身为一个安卓开发人员,却在今年年初才开始接触Kotlin,然后才慢慢引入到项目中来,实在是无法原谅。
然后,截止到现在用了将近一年的Kotlin,回过头来问问自己:好用吗?好学吗?官方支持多吗?和Java兼容好吗?
年初的时候,对这几个问题我是一脸懵逼,评价是不可能评价的,不懂的情况下是肯定不能评价的,只能跟着文档勉强用用这样子。但是G大哥说了,要把它扶正,反正学就对了。
现在,我的感受是,好用、易学、完全兼容Java。当然,大家千万不要完全相信我,这只能说是我个人的感受,各位还是实际写一写,自己会有一个直观的感受。
下面,我会站在一个安卓开发者的角度,以Java为基础和比较对象,粗浅地分析下Kotlin。
语法
Kotlin语法这种东西,我这里只是简单列出一些,用来作为介绍和比较。想了解全面详细的语法,请移步更加官方的、正式的、全面的语法教学。
变量:
Java:
int a = 2;
final int b = 3;
Kotlin:
var a = 2 //var a: Int = 2
val b = 3
可以看到,var是变量,val是常量,而且Kotlin具有类型推断特性,即声明变量时,可以根据值来推断类型,但不要误会,它仍旧时强数据类型。且不向java中有 Integer和int,kotlin中只有Int,也就是没有基本数据类型。
空值:
Java:
String s = null;
//String s;
//String s = "666"
int len = s.length()
Kotlin:
var s: String? = null //带问好即声明可控变量,这个问号不能丢,没有问号便不能赋值null
//lateinit var s: String //声明lateinit的变量,下面引用到时,必须经过赋值,否则抛异常,if(s == null) 这样也会!
//var s = "666"
var len = s?.length
var len = s!!.length //可能引起空指针
在kotlin中,声明一个变量时,需要同时给它赋值,否则就要声明为可空类型或声明延迟初始化。
可空变量在引用时,需要加 '?' 符号,得到的返回值也必定是可空的。或者加 '!!' 操作符,即强行推断为非空,但是可能会引发空指针异常。
判断、强转、迭代:
Java:
if(x instanceof Integer){ }
if(x >= 0 && x <= 10 ){}
final String text = (String) other;
for (int i = 1; i < 11 ; i++) { }
Kotlin
if (x is Int) { }
if (x in 0..10) { }
val text = other as String
for (i in 1 until 11) { }
好吧也没什么说的,貌似是简洁不少?
List和Map:
Java:
List<Integer> numbers = Arrays.asList(1, 2, 3);
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
Kotlin:
val numbers = listOf(1, 2, 3)
var map = mapOf(1 to "One",
2 to "Two",
3 to "Three")
嗯,这个也简洁很多。
创建对象: 这里以Intent为例。
Java:
Intent intent = new Intent(context, ActivityA.class);
Kotlin:
val intent = Intent(context, ActivityA::class.java)
可以看到,在kotlin中是没有 'new' 关键字的,而是直接以调用函数的方式调用类的构造函数,而且java中的一些方法参数为Class对象的,kotlin中以 'XX::class.java' 方式获取。
方法、构造方法、继承:
Java:
public class A extends Object {
int i;
public A(int i) {
this.i = i;
}
public void doIt() {
i = 100;
}
}
Kotlin:
默认构造器中,参数添加var关键字,即可当作类变量使用。
class A(var i: Int) : Any() { //这样写便没有了无参构造函数
fun doIt() {
i = 100
}
}
另一种写法↓
class A() : Any() {
var i: Int = 0
//非抽象类必须有默认构造方法,且其他构造方法必须调用默认构造器
constructor(i: Int) : this() {
this.i = i
}
fun doIt() {
i = 100
}
}
如上,继承Object只是为了举例,kotlin中所有类都默认继承 'Any' 类,当然不写也是可以的。默认类都是final的,若需要继承要用 'open' 关键字修饰。且方法、变量默认都是public的。
kotlin中的方法用 'fun' 声明。
Getter & Setter 及其使用:
Java:
public class A {
private int i = 0;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
//使用:
A a = new A();
int i = a.getI();
a.setI(6);
Kotlin:
class A {
var i = 0
}
//使用:
val a = A()
var i = a.i
a.i = 6
那,kotlin不建议写get和set方法,除非要在存取时做一些附加操作。需要一提的是,kotlin中操作java bean类对象时,直接以上面的方式访问其变量,其实也调用了它的Getter和Setter。
篇幅有限,语法就不过多介绍了。总体来说,只是一些基础语法的不同,但设计思想基本可以完全按Java来。
与Java兼容性、易学程度
好吧,上面语法部分写的太多,这个小节下面发现没什么好写的,不行,这样不和谐,好尴尬呀(ˉ▽ˉ;)
先说总结:因为兼容,所以易用。先拿常用的东西来说,Java中的数据类型和常用的类,Kotlin中基本都有,像List、Map之类的。而且官方生成和Java完全兼容,在从Java像Kotlin迁移的过程中,如果需要用到之前的类或库的时候,可以完全像调用Kotlin代码那样使用。在Java中引入和使用Kotlin也是一样。
而且因为编程思想相同,一个Java类完全可以转换成Kotlin类,只需要修改几个关键字。
网友评论