Kotlin基础学习笔记 (一)
引言
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:
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的缺点,选取了作者:FEELS_CHAOTIC的一部分文章 感性分享