美文网首页Android开发经验谈
Kotlin基础学习笔记 (一)

Kotlin基础学习笔记 (一)

作者: 程序员面试秘籍 | 来源:发表于2020-11-17 21:14 被阅读0次

    引言

    Kotlin 和 java 都是一种静态类型的编程语言。表达式的类型在编译期已经确定,编译期能验证对象是否包含想访问方法或是字段,维护正确性与性能的同时保持源代码的简洁

    静态类型的优点:

    • 性能——方法调用速度更快,因为不需要在运行时才来判断调用的哪个方法

    • 可靠性——编译器验证了程序的正确性,因而运行时崩溃的概率更低

    • 可维护性——抹身代码更容易维护,因为你可以看到代码中用到的对象的类型

    • 工具支持——静态类型使IDE能提供可靠的重构,精确的代码补全特性

      ps:动态类型 编程语言:Groovy、Ruby

      允许定义可以存储任何数据类型的变量,或者返回任何数据类型的函数,并在运行时才解析方法和字段引用。

    • 优点:减少代码量增加创建数据结构的灵活性

    • 缺陷:在编译期不能通过编译期发现拼写类错误,继而导致在运行时出现错误

    Kotlin 的特点

    一门务实、简洁、安全的语言,专注于互操作性。

    Kotlin 语言的优势

    • 1、简洁

      相对于Android、java会减少很多代码;可以通过类型推导的方式判断对象的数据类型

    • 2、安全

      kotlin是空安全的处理的,在编译期就处理了各种null的情况避免空指针时出现在运行时,通过“?”字符

      kotlin在类型转换的时候会将检查和转换被组合成一次操作,一旦检查过类型,就不需要额外的转换就能直接引用属于这类的成员

    • 3、扩展函数

      即使没有权限去访问某个类,也可以扩展这个类的更多特性

    • 4、函数式编程

    kotlin也是基于面向对象的语言。通过lambda表达式,高阶函数等方式更方便的解决问题

    • 5、高度互操作性

    可以继续使用java的代码,比如java方法,继承java类,实现java接口及注解和依赖库,或是混合kotlin和java两种语言混合编写

    函数式编程

    (1)头等函数

    把函数(一部分行为)当作值使用,可以用变量保存它,把它当作参数传递,或者当作其他函数的返回值

    (2)不可变性

    使用不可变对象,这保证了它们的状态在其创建之后不能再变化

    (3)无副作用

    使用的是纯函数。此类函数在输入相同时会产生同样的结果,并且不会修改其他对象的状态,也不和其他交互

    (4)多线程安全

    多线程程序中最大的错误来源之一就是,在没有采用适当同步机制的情况下,在不同的线程上修改同一份数据。假如使用了不可变数据结构和纯函数,就能在一定程度上保证这样不安全的修改根本不会发生了

    (5)易于测试

    没有副作用的函数,可以独立地进行测试,不需要其他繁杂的代码来支撑整个环境

    Kotlin 编译代码

    kotlin编译期会通过代码生成对应.class文件,并通过正在处理的应用程序类型的标准过程打包和执行生成的.class文件

    通过命令行编译代码:

    kotlin <source file or directory> -include -runtime -d <jar name> java -jar <jar name>

    Kotlin 编译器

    IntelliJ IDEA 和 Android Studio 之外还有在线网页编译器 http://try.kotl.in 在线playground 进行小代码示例,但是需要vpn!!

    gradle添加依赖:

    在app的gradle下加入如下代码

    apply plugin: 'kotlin-android'

    apply plugin: 'kotlin-android-extensions'

    在总工程project的gradle下加入如下代码:(大部分是自动生成的)

    buildscript{

    ext.kotlin_version=‘1.2.60'

    ext.dagger_version=‘2.9’ //dagger2版本

    repositories{

    google() or mavenCentral()

    jcenter()

    }

    dependencies {

    classpath 'com.android.tools.build:gradle:3.3.0-alpha03'

    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

    // NOTE: Do not place your application dependencies here; they belong

    // in the individual module build.gradle files
    }

    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.60” -版本注意

    注意:java代码可以直接复制到kotlin类中进行自动转换为对应的kotlin代码;或是通过 Convert java File 头Kotlin File 动作进行转换整个文件

    say many words, 那Kotlin现阶段的缺点呢?

    Kotlin 的缺点

    1、没有命名空间

    kotlin允许在文件中定义顶级的函数和属性,但是会引起所有从kotlin引用的顶级声明无法区分的问题。会给理解代码的时候带来一定的难度。

    例如,你定义这样一个顶级函数:

    fun foo() {...}

    你可以通过 foo() 调用。

    如果你在不同的包里面也存在同样的方法,在调用时就不能明显区分出是调用的哪个方法。你可以通过在前面添加包名的方式去调用,但是如果 Java 约定的包名很深,似乎不太友好。

    一种近似的解决方案是使用单例的 object 类。

    object FooActions { fun foo() {...}}

    这样你在 Kotlin 中可以通过 FooActions.foo() 调用,但是在 Java 中你必须要这样 FooActions.INSTANCE.foo()这样调用,这看起来很麻烦。

    你也可以使用 @JvmStatic 去注解该方法,从而省掉INSTANCE。

    2、没有静态修饰符

    2. 没有静态修饰符

    Kotlin为静态函数和属性提供了一个和 Java 不一样的处理方式。并不是说有多烂,只是觉得让代码变得不干净而且没有必要。

    例如,在 Android 的 View 类中定义的静态属性 View.VISIBLE 和静态函数 View.inflate

    public class View {

    public static final int VISIBLE = 0x00000000;

    public static final int INVISIBLE = 0x00000004;

    public static View inflate(Context context, int resource) {...}

    }

    这个定义是简单的。然而,在 Kotlin 代码中:

    class View {

    companion object {

    @JvmField

    val VISIBLE: Int = 0x00000000

    @JvmField

    val INVISIBLE: Int = 0x00000004
    @JvmStatic

    fun inflate(context: Context, resource: Int) {...}

    }

    }

    注:companion object为伴生对象

    尽管 Kotlin 的版本并没有那么恐怖,但是它的复杂程度超过了我对这门语言的预期。如果去掉注解,你在 Java 中就不得不使用这样可怕的语法去调用:

    // With annotations:

    View.VISIBLE;

    //Without annotations:

    View.Companion.getVISIBLE();

    3. 编译方法数量

    Kotlin 肯定会减少项目中的代码行数,但是它也会提高代码在编译以后的方法数。主要原因就是 Kotlin 属性的实现方式。

    和 Java 不一样,Kotlin 没有提供单独定义域的方式。你必须使用 val 或者 var 来声明变量。这样有一个好处,就是省去了像 Java 一样定义 getters 和 setters 方法。

    但是这需要一定的成本。每一个public的 val 变量都会生成一个「支持域」和一个能被 Java 调用的 getter 方法。每一个public的 var 变量都会生成 getter 和 setter 方法。

    // kt 文件:

    // 默认就是public,无需额外添加public修饰符

    val strValPublic: String = "strValPublic"

    var strVarPublic: String = "strVarPublic"

    // 以下是反编译结果:

    public final class VarAndValKt {

    @NotNull

    private static final String strValPublic = "strValPublic";

    @NotNull

    private static String strVarPublic = "strVarPublic";

    @NotNull

    public static final String getStrValPublic() {

    return strValPublic;

    }

    @NotNull

    public static final String getStrVarPublic() {

    return strVarPublic;

    }
    public static final void setStrVarPublic(@NotNull String var0) {

    Intrinsics.checkParameterIsNotNull(var0, "<set-?>");

    strVarPublic = var0;

    }

    }

    拓展:Intrinsics.checkParameterIsNotNull 方法其实很简单,原理:

    public static void checkParameterIsNotNull(Object value, String paramName) {

    if (value == null) {

    throwParameterIsNullException(paramName);

    }

    }

    其实所有空安全的秘密都在这个类里面了

    庆幸的是,私有属性的 getters 和 setters 会生成域而不是生成方法。

    // kt文件:

    private val strValPrivate: String = "strValPrivate"

    private var strVarPrivate: String = "strVarPrivate"

    // 以下是反编译结果:

    public final class VarAndValKt {

    private static final String strValPrivate = "strValPrivate";

    private static String strVarPrivate = "strVarPrivate";

    }

    所以如果你把项目中Java代码转成Kotlin,而且之前的 Java 代码中定义了大量的公开域(这在定义常量的时候很常见),你会惊奇的发现最终编译生成的方法数量大幅上升。

    如果你的 Android 应用快接近方法数限制了,我建议你为不需要自定义 getter 方法的常量加上 @JvmField 注解。这样会阻止 getters 方法的生成,从而减少你的方法数。

    // kt 文件:

    @JvmField

    val strValPublic: String = "strValPublic"

    @JvmField

    var strVarPublic: String = "strVarPublic"

    // 以下是反编译结果:

    // 注意看,get set方法消失,取而代之的是private修饰符变成了public

    public final class VarAndValKt {

    @JvmField

    @NotNull

    public static final String strValPublic = "strValPublic";

    @JvmField

    @NotNull

    public static String strVarPublic = "strVarPublic";

    }



    由于简书限制网盘链接,在我主页扫描我的二维码,我免费分享给你

    相关文章

      网友评论

        本文标题:Kotlin基础学习笔记 (一)

        本文链接:https://www.haomeiwen.com/subject/tepfiktx.html