Kotlin代码进阶(一)

主构造器与次构造器

次构造器的写法

class LessonViewHolder : BaseViewHolder {
        //次构造器  internal为可见性修饰符
        internal constructor(itemView: View):super(itemView)
}

主构造器写法

class LessonViewHolder internal constructor(itemView: View) : BaseViewHolder(itemView) {

}

User类的主构造器与次构造器

次构造器

package com.example.app.entity

class User {

    //kotlin中默认有get set方法
    var username: String? = null
    // ?表示可以赋值为null
    var password: String? = null
    var code: String? = null

    //空构造函数
    constructor() {

    }

    //带参数的构造函数
    constructor(username: String?, password: String?, code: String?) {
        this.username = username
        this.password = password
        this.code = code
    }
}

主构造器

package com.example.app.entity

class User constructor() {

    //kotlin中默认有get set方法
    var username: String? = null
    // ?表示可以赋值为null
    var password: String? = null
    var code: String? = null


    //带参数的构造函数  : this()  调用无参主构造器
    constructor(username: String?, password: String?, code: String?) : this() {
        this.username = username
        this.password = password
        this.code = code
    }
}

写法进一步优化

优化前:

class Lesson constructor(date: String?, content: String?, state: State?) {


    var date: String? = null
    var content: String? = null
    var state: State? = null

    init {
        this.date = date
        this.content = content
        this.state = state
    }

}

优化后:

class Lesson constructor(var date: String?, var content: String?, var state: State?) {

}

注意:主构造器上的参数只有在init初始化里面能访问,其他方法里不能访问

           如果想访问,主构造器的参数要定义成成员属性,就是val或者var

User类写法进一步优化

优化前:

class User constructor() {

    //kotlin中默认有get set方法
    var username: String? = null
    // ?表示可以赋值为null
    var password: String? = null
    var code: String? = null


    //带参数的构造函数  : this()  调用无参主构造器
    constructor(username: String?, password: String?, code: String?) : this() {
        this.username = username
        this.password = password
        this.code = code
    }
}

优化后:


//如果要定义一个数据类,都要重写toString()、hashCode()方法
//在Java中药自己手动生成
//在Kotlin中直接定义成数据类就可以了 用data class

data class User constructor(var username: String?, var password: String?,var code: String?) {
    //空参构造器必须调用主构造器
    constructor():this(null,null,null)

}

Kotlin中的==与===

Kotlin中的

==:其实是调用的equals方法

=== :比较的是地址值

Kotlin代码转化为Java代码

Tools-->Kotlin-->Show Kotlin Bytecode-->Decompile

以User类为例子:

转化前:

package com.example.app.entity


//如果要定义一个数据类,都要重写toString()、hashCode()、equals方法、copy方法
//在Java中需要自己手动生成
//在Kotlin中直接定义成数据类就可以l 用data class Kotlin会自动生成这些方法
data class User constructor(var username: String?, var password: String?,var code: String?) {
    //空参构造器必须调用主构造器
    constructor():this(null,null,null)

}

转换后:

package com.example.app.entity;

import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Metadata(
   mv = {1, 1, 15},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000$\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0010\n\u0002\u0010\u000b\n\u0002\b\u0002\n\u0002\u0010\b\n\u0002\b\u0002\b\u0086\b\u0018\u00002\u00020\u0001B\u0007\b\u0016¢\u0006\u0002\u0010\u0002B#\u0012\b\u0010\u0003\u001a\u0004\u0018\u00010\u0004\u0012\b\u0010\u0005\u001a\u0004\u0018\u00010\u0004\u0012\b\u0010\u0006\u001a\u0004\u0018\u00010\u0004¢\u0006\u0002\u0010\u0007J\u000b\u0010\u0010\u001a\u0004\u0018\u00010\u0004HÆ\u0003J\u000b\u0010\u0011\u001a\u0004\u0018\u00010\u0004HÆ\u0003J\u000b\u0010\u0012\u001a\u0004\u0018\u00010\u0004HÆ\u0003J-\u0010\u0013\u001a\u00020\u00002\n\b\u0002\u0010\u0003\u001a\u0004\u0018\u00010\u00042\n\b\u0002\u0010\u0005\u001a\u0004\u0018\u00010\u00042\n\b\u0002\u0010\u0006\u001a\u0004\u0018\u00010\u0004HÆ\u0001J\u0013\u0010\u0014\u001a\u00020\u00152\b\u0010\u0016\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0017\u001a\u00020\u0018HÖ\u0001J\t\u0010\u0019\u001a\u00020\u0004HÖ\u0001R\u001c\u0010\u0006\u001a\u0004\u0018\u00010\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\b\u0010\t\"\u0004\b\n\u0010\u000bR\u001c\u0010\u0005\u001a\u0004\u0018\u00010\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\f\u0010\t\"\u0004\b\r\u0010\u000bR\u001c\u0010\u0003\u001a\u0004\u0018\u00010\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u000e\u0010\t\"\u0004\b\u000f\u0010\u000b¨\u0006\u001a"},
   d2 = {"Lcom/example/app/entity/User;", "", "()V", "username", "", "password", "code", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "getCode", "()Ljava/lang/String;", "setCode", "(Ljava/lang/String;)V", "getPassword", "setPassword", "getUsername", "setUsername", "component1", "component2", "component3", "copy", "equals", "", "other", "hashCode", "", "toString", "app_debug"}
)
public final class User {
   @Nullable
   private String username;
   @Nullable
   private String password;
   @Nullable
   private String code;

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

   public final void setUsername(@Nullable String var1) {
      this.username = var1;
   }

   @Nullable
   public final String getPassword() {
      return this.password;
   }

   public final void setPassword(@Nullable String var1) {
      this.password = var1;
   }

   @Nullable
   public final String getCode() {
      return this.code;
   }

   public final void setCode(@Nullable String var1) {
      this.code = var1;
   }

   public User(@Nullable String username, @Nullable String password, @Nullable String code) {
      this.username = username;
      this.password = password;
      this.code = code;
   }

   public User() {
      this((String)null, (String)null, (String)null);
   }

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

   @Nullable
   public final String component2() {
      return this.password;
   }

   @Nullable
   public final String component3() {
      return this.code;
   }

   @NotNull
   public final User copy(@Nullable String username, @Nullable String password, @Nullable String code) {
      return new User(username, password, code);
   }

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

      if ((var4 & 2) != 0) {
         var2 = var0.password;
      }

      if ((var4 & 4) != 0) {
         var3 = var0.code;
      }

      return var0.copy(var1, var2, var3);
   }

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

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

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

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

这样就可以看出Kotlin中数据类 data class 自动帮助我们生成了getter 、setter、copy()、toString()、hashCode()、equals方法

Kotlin中的 ?:

 var date = lesson.date?:"默认数据"

这一行代码的意思是:lesson.date  为null吗? 不为null就取lesson.date的值,为null就取默认数据

Kotlin中的when可以有返回值

kotlin中 if、try catch也可以有返回值

优化前:

           if (state != null) {
                setText(R.id.tv_state, state.stateName())
                var colorRes = R.color.playback
                when (state) {
                    Lesson.State.PLAYBACK -> colorRes = R.color.playback
                    Lesson.State.LIVE -> colorRes = R.color.live
                    Lesson.State.WAIT -> colorRes = R.color.wait
                }
                val backgroundColor = itemView.context.getColor(colorRes)
                getView<View>(R.id.tv_state).setBackgroundColor(backgroundColor)
            }

优化后:

            if (state != null) {
                setText(R.id.tv_state, state.stateName())
                var colorRes = when (state) {
                    Lesson.State.PLAYBACK -> R.color.playback
                    Lesson.State.LIVE -> R.color.live
                    Lesson.State.WAIT -> R.color.wait
                }
                val backgroundColor = itemView.context.getColor(colorRes)
                getView<View>(R.id.tv_state).setBackgroundColor(backgroundColor)
            }

自定义操作符operator

var list: List<String> = ArrayList()

kotlin中取集合元素用:list[index]

其实点击进去看,会发现调用的就是get ,这是自定义操作符operator    []-->get

public operator fun get(index: Int)

Kotlin中的循环语句

优化前:for  in

        val playbackLessons = ArrayList<Lesson>()
        for (lesson in lessons) {
            if (lesson.state === Lesson.State.PLAYBACK) {
                playbackLessons.add(lesson)
            }
        }
        activity.showResult(playbackLessons)

优化后:forEach


        val playbackLessons = ArrayList<Lesson>()
        lessons.forEach {
            if (it.state === Lesson.State.PLAYBACK) {
                playbackLessons.add(it)
            }
        }
        activity.showResult(playbackLessons)

优化后:filter


        //过滤掉 it.state === Lesson.State.PLAYBACK 返回一个过滤后的数据
        val playbackLessons = lessons.filter { it.state === Lesson.State.PLAYBACK }
        activity.showResult(playbackLessons)

repeat 、until

    repeat(10){
       println(it)
    }
    for(i in 0 until 10){
        println(i)

    }

会打印出0---9

Kotlin可以函数嵌套函数

方法嵌套好处:在别的地方就调用不到这个方法;方便找代码;内部函数可以访问外部函数的属性

方法嵌套劣势:每次调用的时候会额外生成一个对象,不建议循环调用

嵌套之前:

private fun login() {
        //Java 中的final 表示不可变引用 getText kotlin中直接.text
        val username:String = et_username.text.toString()
        val password:String= et_password.text.toString()
        val code:String= et_code.text.toString()

        //Kotlin 中创建对象不用new
        val user: User = User(username,password,code)

        if(verify(user)){
            CacheUtils.save(usernameKey, username)
            CacheUtils.save(passwordKey, password)
            //Kotlin中 LessonActivity.class 要写成LessonActivity::class.java
            //Kotlin中获取class 用LessonActivity::class 要转化成java中class-->LessonActivity::class.java
            startActivity(Intent(this, LessonActivity::class.java))
        }
    }

    private fun verify(user: User): Boolean {
        if(user.username!=null && user.username!!.length<4){
            toast("用户名不合法")
            return false
        }
        if (user.password != null && user.password!!.length < 4) {
           toast("密码不合法")
            return false
        }
        return true
    }

嵌套之后:

    private fun login() {
        //Java 中的final 表示不可变引用 getText kotlin中直接.text
        val username: String = et_username.text.toString()
        val password: String = et_password.text.toString()
        val code: String = et_code.text.toString()
        
        //Kotlin 中创建对象不用new
        val user: User = User(username, password, code)

        //方法嵌套好处:在别的地方就调用不到这个方法;方便找代码;内部函数可以访问外部函数的属性

        //方法嵌套劣势:每次调用的时候会额外生成一个对象,不建议循环调用
        fun verify(): Boolean {
            if (user.username != null && user.username!!.length < 4) {
                toast("用户名不合法")
                return false
            }
            if (user.password != null && user.password!!.length < 4) {
                toast("密码不合法")
                return false
            }
            return true
        }
        if (verify()) {
            CacheUtils.save(usernameKey, username)
            CacheUtils.save(passwordKey, password)
            //Kotlin中 LessonActivity.class 要写成LessonActivity::class.java
            //Kotlin中获取class 用LessonActivity::class 要转化成java中class-->LessonActivity::class.java
            startActivity(Intent(this, LessonActivity::class.java))
        }
    }

getter与setter、@JvmStatic 及 @get的使用

优化前:

class BaseApplication : Application() {

    //object 修饰的对象中的变量和函数都是静态的,
    //我们只想让类中的一部分函数和变量是静态的就用伴生对象

    companion object {
        lateinit var currentApplication: Context

        @JvmStatic
        fun currentApplication(): Context {
            return currentApplication
        }
    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        currentApplication = this
    }

}

优化后:

class BaseApplication : Application() {

    //object 修饰的对象中的变量和函数都是静态的,
    //我们只想让类中的一部分函数和变量是静态的就用伴生对象

    companion object {
        //会自动生成 getter与setter
        @JvmStatic
        //自定义获取Context 的文件名
        @get:JvmName("currentApplication")
        lateinit var currentApplication: Context
            //让setter不能访问
            private set

    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        currentApplication = this
    }

}

 使用=进行函数简化

简化前:

    //Unit代表没有
    @JvmStatic
    fun save(key: String?, value: String?): Unit {
        SP.edit().putString(key, value).apply()
    }

    //String? 返回值后面加上一个问号,代表返回值可能为null
    @JvmStatic
    fun get(key: String?): String? {
        return SP.getString(key, null)
    }

简化后:

    @JvmStatic
    fun save(key: String?, value: String?): Unit = SP.edit().putString(key, value).apply()

    @JvmStatic
    fun get(key: String?): String? = SP.getString(key, null)
发布了272 篇原创文章 · 获赞 68 · 访问量 40万+

猜你喜欢

转载自blog.csdn.net/u014005316/article/details/104353110