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的一部分文章 感性分享
 
 
posted @ 2018-08-14 09:42  想不起来的角落  阅读(442)  评论(0编辑  收藏  举报