kotlin 的简洁性

1. Null-Safety 空安全

  • 化空对象的处理(防止空指针)

Kotlin 的设计理念之一就是希望消除代码中 null reference 造成 NullPointerException 的危害。

在声明一个变量的时候,必须要指定它是否是可以为空的,可以为空和不可以为空将会是按照不同的类型处理,比如 String 和 String?是不同的类型

空安全特性在实际使用中确实能带来很大的好处,能够在语言层面强制要求开发者对所有的可能为空的变量进行处理,如此即可大大减少代码中繁琐的判空, 并尽可能避免 NullPointerException的产生。

val userName = a?.b?.c?.d ?: ""

多了这么一块代码:

Intrinsics.checkParameterIsNotNull(name, "name");
 
public static void checkParameterIsNotNull(Object value, String paramName) {
        if (value == null) {
            throwParameterIsNullException(paramName);
        }
    }

2. 强制 setter 和 getter

  • 属性访问,代替 Get/Set 方法

Java的规范写法中会提倡使用 setter 和 getter 的写法,而不是直接对熟悉进行访问。这样做的好处就不赘述了。只是这样写的话,会带来很多的样板代码,会在项目中出现大量的 setXXX 和 getXXX 样式的代码。而Kotlin则是直接在语法层面解决了这个问题。

Kotlin中把对熟悉的访问强制使用setter 和 getter,那怕看起来像是直接读取一个成员变量,其实本质上还是访问的它的 getter 方法。这样就直接封死了直接操作成员变量的路

//Kotlin代码
class User {
    var name :String?=null
}

//Java代码
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

对应生成的 java 代码:

public final class User {
   @Nullable
   private String name;

   @Nullable
   public final String getName() {
      return this.name;
   }

   public final void setName(@Nullable String var1) {
      this.name = var1;
   }
}

3. 默认构造函数

  • Kotlin代码
class User(var name: String)
  • Java代码
public class User {

    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name.toUpperCase();
    }

    public void setName(String name) {
        this.name = name.toUpperCase();
    }
}

kotlin 对应生产的 java 代码:

public final class User {
   @NotNull
   private String name;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.name = var1;
   }

   public User(@NotNull String name) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
   }
}

4. 对象属性调用简化(使用with、apply、let等)

  • Kotlin代码(可避免重复写对象的名字)
val user = User()
with(user)
{
    name = "jerry"
    age = 18
}
  • Java代码
User user = new User();
user.setName("jerry");
user.setAge(18);

5. 安卓自动绑定xml文件中控件定义

不再需要使用 findViewByIdButterKnife,使用样例:

import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        .....
        textView.text = "hello"
    }
}

详细文档,可参考:《使用Kotlin Android Extensions代替ButterKnife和findViewById》

6. 简化Parcelable实现

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
class User(var age: Int,var name: String): Parcelable

7. 简化单例对象构造

  • Kotlin代码(定义类名时采用object即可)
object User
{
    fun test()
    {
    }
}
  • Java代码
public final class User {
    public static final User instance = new User();

    public void test() {
    }

    public static User getInstance() {
        return instance;
    }

    private User() {
    }
}

kotlin 生成的 java 代码:

public final class User {
   public static final User INSTANCE;

   public final void test() {
   }

   private User() {
   }

   static {
      User var0 = new User();
      INSTANCE = var0;
   }
}

8.使用字符串模版简化字符串拼接

  • Kotlin代码
val info = "name:$name,age:$age"

(new StringBuilder()).append("name:").append(name).append(",age:").append(age).toString();
  • Java代码
String info = "name:" + name + ",age:" + age;

9. 使用 when进行分支判断(替代Java中 switch)

  • Kotlin代码
var id = 1
when (id) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("id 不是 1 ,也不是 2")
    }
}

另外kotlin还支持将同一类的条件写在一起,如 2,3 -> print("x == 2或者3")

  • Java代码
int x = 1;
switch (x) {
    case 1:
        print("x==1");
        break;
    case 2:
        print("x==2");
        break;
    default:
        print("id 不是 1 ,也不是 2");
        break;
}

10. Data class

App 通常需要一些基本的l类别來封装 Domain,而 Kotlin 的 data class 减少了 Java 中不可避免的样板代码,data class compiler 自动生成 getter, setter, equals(), hashCode(), toString() 以及 copy() 等方法

data class User(val username: String, val age: Int)
fun main() {
    val user = User("Jerry", 18)
    val (username, age) = user
    println("username:$username,age:$age")
}
public final class User {
   @NotNull
   private final String username;
   private final int age;

   @NotNull
   public final String getUsername() {
      return this.username;
   }

   public final int getAge() {
      return this.age;
   }

   public User(@NotNull String username, int age) {
      Intrinsics.checkParameterIsNotNull(username, "username");
      super();
      this.username = username;
      this.age = age;
   }

   @NotNull
   public final String component1() {
      return this.username;
   }

   public final int component2() {
      return this.age;
   }

   @NotNull
   public final User copy(@NotNull String username, int age) {
      Intrinsics.checkParameterIsNotNull(username, "username");
      return new User(username, age);
   }

   // $FF: synthetic method
   public static User copy$default(User var0, String var1, int var2, int var3, Object var4) {
      if ((var3 & 1) != 0) {
         var1 = var0.username;
      }

      if ((var3 & 2) != 0) {
         var2 = var0.age;
      }

      return var0.copy(var1, var2);
   }

   @NotNull
   public String toString() {
      return "User(username=" + this.username + ", age=" + this.age + ")";
   }

   public int hashCode() {
      String var10000 = this.username;
      return (var10000 != null ? var10000.hashCode() : 0) * 31 + this.age;
   }

   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof User) {
            User var2 = (User)var1;
            if (Intrinsics.areEqual(this.username, var2.username) && this.age == var2.age) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}

User user = new User("Jerry", 18);
String username = user.component1();
int age = user.component2();
String var4 = "username:" + username + ",age:" + age;
boolean var5 = false;
System.out.println(var4);

11. 协程coroutines

协程最主要的优点还不在于减少代码,而在于使调用逻辑简化,使得我们不必使用 AsyncTask 或者 RxJava 这样复杂的方案.

GlobalScope.launch {
    doSomething()
    withContext(Dispatchers.Main)
    {
        textView.text = "coroutines完成执行"
        Toast.makeText(this@MainActivity, "coroutines hooray", Toast.LENGTH_SHORT).show()
    }
}

12. Extension Functions:

JetBrains 在设计之初就考虑到我們很習习惯Java 中的一些以 Utils 结尾的工具类,像是 FileUtils, StringUtils 等等。

Kotlin 中采用 extension 的概念来大幅增加可能性并缩减代码量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值