美文网首页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