Kotlin从入门到沉迷
2017年5月份,Google宣布kotlin正式成为Android开发语言之一,也就是说kotlin得到Android的官方支持了!kotlin也逐渐被许多Android开发者投入到实际的开发中,无论是哪种开发语言,开发者都会对其存在赞赏和质疑的声音,kotlin当然也不例外,但是在与其他开发者交流的时候,发现对kotlin称赞有加的声音远远大于质疑的声音,这就让我对kotlin产生更大的好奇心,决定开始用kotlin来写demo作为练手。
在使用kotlin的过程中,与Java对比,kotlin有个非常明显的优点,那就是代码异常简洁!爱上kotlin之后,你会非常嫌弃Java的啰嗦代码!
下面,让我们来看看,Java和kotlin之间的对比
基本数据类型
JAVA | Kotlin |
---|---|
int | Int |
long | Long |
short | Short |
char | Char(kotlin中为独立类型) |
float | Float |
double | Double |
byte | Byte |
boolean | Boolean |
可以看出,Kotlin的基本数据类型,写法和Java基本数据类型的包装类是一样的(除了int的Integer)
基本语法
声明变量
Java
int i = 0;
String name = "test";
final String userName = "ywq"
String nullAbleStr;
User user = new User("ywq",1)
Kotlin
var i = 0 //自动推断为整型
var name = "test" //自动推断为字符串
val userName = "ywq" //val为只读标志,声明后不能更改,相当于Java中的final
var nullAbleStr:String?= null //声明可能为空的字符串变量
lateinit var phone :String //该变量延迟赋值
val user = User("ywq",1)
kotlin语法规则
{var(val)} {变量名}{:}{类型}={对象}
或者 (类型后面加一个问号,代表该对象可能为空)
{var} {变量名}{:}{类型?}=null
lateinit var 声明的变量在使用前必须初始化,否则会抛出kotlin的空指针异常
方法
Java
public int getStringLength(String content){
if(content!=null){
content = content.replace("*","");//移除特殊字符
return content.length();
}
return 0;
}
kotlin
fun getStringLength(content:String?):Int{
return content?.replace("*","")?.length
}
//或者
fun getStringLength(content:String?):Int = content?.replace("*","")?.length
对比起来,kotlin的代码异常简约,一个问号取代以往Java判空的代码,避免处理不当引起的空指针异常
类
Java
public class User{
private String name;
private int age;
public User(String name,int age){
this.name = name ;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
//内部类
private class UserInfo{
}
}
kotlin
class User(var name:String,var age:Int){
//内部类
inner class UserInfo
}
kotlin的代码量简直少的丧心病狂啊!虽然我们用Java写实体类的时候,一般会用IDE自动生成get/setter,但是代码看起来多啊,而且很啰嗦很多余!
注意,kotlin的类默认为final类,如果需要创建能被继承的父类,class前加上open关键字
如
open class class User(var name:String,var age:Int)
我们平常使用的一些POJO类甚至可以直接这样声明,非常直观
data class User(val name:String,val age:Int)
单例
在java中深入探讨一个可靠的、线程安全的、开销小的单例其实需要花一定篇幅,而在kotlin中,可以通过object关键字定义单例:
object Singleton {
fun doSomething() {
}
}
然后直接调用
//kotlin
Singleton.doSomething()
//在Java中调用kotlin的单例
Singleton.INSTANCE.doSomething()
接口
Java
interface OnClickListener{
boolean onClick(View view)
}
kotlin
interface OnClickListener{
fun onClick(view:View):Boolean
}
静态变量
Java
public class Constants{
public static final int SUCCESS = 200;
}
kotlin
class Constants{
companion object {
const val SUCCESS = 200
}
}
kotlin的class不支持静态变量,必须通过伴生对象 companion object来声明,这一点反倒没有Java方便
类型转换
java
String numStr = "100";
public void change(Content context){
int numInt = Integer.parseInt(numStr);
long numLong = Long.parseLong(numStr);
long numShort = Short.parseShort(numStr);
if(context instanceof Activity){
Activity activity = (Activity)context;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//do on uithread
}
});
}
}
kotlin
var numStr = "100"
fun change(context:Context){
val numInt = numStr.toInt()
val numLong = numStr.toLong()
val numShort = numStr.toShort()
if(context is Activity){
val activity = context
activity.runOnUiThread{
//do on uithread
}
}
}
kotlin中判断对象是否为某种类型,用的是 is 关键字,和java中的 instanceof 相比而言,不但直观而且很生动!况且从以上的代码比较看得出,kotlin在判断类型成功后,不需要手动去强制转换对象类型,啰嗦的Java!!!
字符串拼接
java
String text = "userName : " + user.getName();
kotlin
val text = "userName : ${user.name}"
条件表达式
if 语句
Java
if( a == b){}
if( a>=0 && a <=10){}
if( a>0 && a <10){}
kotlin
if( a == b){}
if( a in 0..10){} // 也可以按照Java写法 if( a>=0 && a <=10){}
if(a in 1 until 10) //也可以按照Java写法 if( a>0 && a <10){}
三元运算符
java
int num = a > b ? a :b;
Kotlin
val num = if (a > b) a else b
switch语句
java
public boolean isSuccess(int code){
boolean flag = false
switch(code){
case 200:
flag = true;
break;
case 400:
flag = true
break;
default :
flag = false
break;
}
return flag;
}
kotlin
public fun isSuccess(code:Int):Boolean{
val flag = when(code){
200,400-> true
else -> false
}
return flag
}
when语句
在kotlin中when语句非常强大,是switch的强化版,具备自动转型、无自变量、具备返回值等功能
自动转型
when(context){
is Activity -> context.runOnUiThread{
}
is Service -> toast("i am service")
}
无自变量的when
public fun get(number:Int,str:String,v:View):String{
val res = when{
number in 0..100 -> "数字范围在0到100"
str.contains("loading") -> "内容包含loading"
v is Button -> "view is Button"
else -> "undone"
}
return res
}
一入when深似海,从此if是路人。特别是存在多种条件判断的场景,用if语句看起来会特别臃肿,强烈推荐用when,简洁明了
lambda
Java1.8之后,也增加了lambda表达式,即函数式编程,Java因此变得更加直观简约。kotlin也一样支持lambda,甚至比Java更加简约,但其实作用都是取代了匿名内部类对象。
以往的Java
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//do something
}
});
1.8后的Java
loginBtn.setOnClickListener(view -> {
//do something
})
kotlin
//存在三种写法
loginBtn.setOnClickListener(object: View.OnClickListener {
override fun onClick(p0: View?) {
//do something
}
})
loginBtn.setOnClickListener{
//do something
}
loginBtn.setOnClickListener{
view ->
//do something
}
扩展函数
kotlin的扩展函数非常有用,能够让你减少各种Util工具类,比如
StringUtil.getLastChar("msg");
用了kotlin之后,我们可以不再去写一个StringUtil了,而是可以在任何一个地方增加以下属于String类的扩展方法
fun String.lastChar():Char{
return this.get(this.length-1);
}
这是,我们可以直接操作string了
"test".lastChar()
其他语法糖
部分语法糖可能与Java1.8重复
list遍历,获取符合对应条件的列表
val list = ArrayList<User>()
//遍历所有用户输出年龄
list.forEach{
println("userAge : ${it.age}")
}
//获取年纪大于10岁的用户
val list2 = list.filter {
it.age >10
}
//判断是否所有用户年龄都小于9岁 flag为Boolean值
val flag = list.all{
it.age <9
}
//判断是否存在用户年龄大于49岁
val flag = list.any{
it.age > 49
}
//找到所有年龄为10的用户,输出前三位的姓名和性别
list.filter{
it.age == 10
}.map{
"name = ${it.name} age = ${it.sex}"
}.take(3).forEach{
println(it)
}