kotlin 入门

一、准备工作

  1. Kotlin语言介绍

    1. Kotlin 是 JetBrains 在 2010 年推出的基于 JVM 的新编程语言。开发者称,设计它的目的是避免 Java 语言编程中的一些难题。比如:在 Kotlin 中类型系统控制了空指针引用,可以有效避免 Java 中常见的NullPointException。

    2. 相比于 Java,Kotlin 有着更好的语法结构,安全性和开发工具支持。

    3. Kotlin 中没有基础类型,数组是定长的,泛型是安全的,即便运行时也是安全的。此外,该语言支持闭包,还可通过内联进行优化。不过,它不支持检查异常(Checked Exceptions),许多语言设计者认为这是它的瑕疵。不论如何,重要的是 Java 和 Kotlin 之间的互操作性:Kotlin 可以调用 Java,反之亦可。

  1. 环境搭建

    1. Android Studio支持Kotlin环境,Android开发者可以直接使用

    2. 如果是自己练习一些语法什么的,强烈建议使用Intellij IDEA

    3. 安装 Intellij IDEA

      1. 官网下载,可以使用社区版。 https://www.jetbrains.com/idea/download/

      2. 新建工程

        1. 打开 IDEA -> New Project -> Lanuge 选Kotlin 即可

        2. 下载依赖需要等一会

        3. 在工程中新建 kt 文件练习

        4. 入口即是一个 main 函数,如下

三、快速上手

  1. Kotlin 基础语法

文件以kt结尾,变量声明,var,val,空安全,函数声明,模板语法($)

  1. 与 Java 代码互调

    1.   Java调用Kotlin函数: Kotlin文件中的函数编译之后变成 UntilsKt.echo()

     

    // Utils.kt fun echo(name: String) { println("$name") } // Main.java public static void main(String[] args) { UtilsKt.echo("hello"); }

    1.   object Test : 内部匿名类,也是一种单例实现方法

     

    object Test { fun sayMessage(msg: String) { println(msg) } } kotlin code Test.sayMessage("hello") java code Test.INSTANCE.sayMessage("hello");

    1.   传class时的写法

     

    java code TestMain.class kotlin code TestMain::class.java 例如: private val log: LogHelper = LogHelper(AiVisualService::class.java.simpleName)

    1.   关键字冲突: 用两个反引号转义

       

      java code public class JavaMain { public static String in = "in"; } kotlin code fun main(args: Array) { println(JavaMain.`in`) }

  1. 新手使用kotlin常碰到的问题

  1. Kotlin 没有封装类

没有封装类,只有基础类型,比如没有 Integer, 跟java不一样

  1. Kotlin 类型空值敏感

 
  

java code String format(String str) { return str.isEmpty() ? null : str; } kotlin code fun function(str: String) { val fmt1 = format(str) // 自动推断类型,String!, 临时的兼容类型 println(fmt1.length) // 运行时报空指针 val fmt2:String = format(str) // 会不会有问题? val fmt3:String? = format(str) println(fmt3?.length) // 空安全,不会有问题 } fun main(args: Array) { function("") }

  1. Kotlin 没有静态变量与静态方法

 
  

object Test { val TAG:String = "test" fun sayMessage(msg: String) { println(msg) } } kotlin code Test.sayMessage("hello") java code Test.INSTANCE.sayMessage("hello"); 思考:java如何不加添加 INSTANCE? 答案:@JvmStatic 关键字 object Test { @JvmStatic fun sayMessage(msg: String) { println(msg) } } kotlin code Test.sayMessage("hello") java code Test.sayMessage("hello");

四、函数与lambda闭包

  1. 函数的特性语法

函数是一等公民,而不是跟Java一样只有方法

 
  

fun echo(name: String) { println("$name") } fun echo(name: String = "ZhangTao") { println("$name") } fun echo(name: String) = println("$name") // 只有一个语句时,可这样简写

  1. 嵌套函数

一般情况下不推荐使用,可以在特殊场景使用,如下

用途:在某些条件下触发递归的函数,或不希望被外部函数访问到的函数

 
  

fun function() { val str = "hello world" fun say(count: Int = 10) { println(str) if (count > 0) { say(count - 1) } } say() }

  1. 扩展函数

kotlin code val file = File() val content = file.readText() java code String content = FilesKt.readText(file, Charsets.UTF_8);

主要用途:对第三方SDK,或不能控制的类,需要扩展时,可以使用扩展函数。

注意:静态的给一个类添加成员变量或成员方法,不具备动态特性。

  1. Lambda 闭包语法

 
  

fun main(args: Array) { val thread = Thread({ -> Unit }) thread.start() } 如果没有参数,可省略箭头 如果Lambda是最后一个参数,可把花括号放到小括号外边(后边)来写 如果只有一个参数,并且是Lambda,可以省略小括号 fun main(args: Array) { val thread = Thread {} thread.start() }

Lambda闭包声明

 
  

val echo = { name: String -> println(name) } fun main(args: Array) { echo.invoke("Zhang Tao") echo("Zhang Tao") }

Lambda 最多只有22个参数,如何突破限制?

  1. 高阶函数

  1. 高阶:函数(或Lambda)的参数又是一个函数(或Lambda)

 
  

fun onlyif(isDebug: Boolean, block:() -> Unit) { if (isDebug) block() } fun main(args: Array): Unit { onlyif(true) { println("") } }

  1. 一等公民:函数是一等公民

 
  

val runnable = Runnable { println("Runnable::run") } val function: () -> Unit function = runnable::run 使用(接前一段代码): onlyif(true, function)

  1. 内联函数

Kotlin 的 Lambda 是一个匿名对象

可以使用 inline 修饰方法,这样当方法在编译 时就会拆解方法的调用为语句调用,进而减少 创建不必要的对象

最后:inline不要滥用,最好只用于修饰高阶函数

五、类与对象

  1. 构造函数

  1. 认识一下类

 
  

class MainActivity : AppCompatActivity() class MainActivity : AppCompatActivity(), OnClickListener Kotlin 的类默认是 public final 的 open class MainActivity : AppCompatActivity() open class MainActivity : AppCompatActivity(), OnClickListener

  1. 主构造函数

主构造函数: 规范来说,都是以_xxx的形式命名的,临时的输入类型,不能直接用,需要通过声明接收下来,成为变量才

 
  

class Test03(_name:String,_sex:Char,_age:Int,_info:String) //主构造函数 { var sex=_sex get() = field var age=_age+10 get() = field var info=_info get() = field var name=_name get() = field //get函数不允许私有化 private set(value) {field=value} fun show(){ println(name) // name==this.getName() println(sex) println(info) println(age) } } fun main() { val test03 = Test03("李渐渐", '女', 10, "信息") //test03.name="李防范" set被私有化了,不能调用 test03.show() }

  1. 次级构造函数

使用次构造函数时,先调用主构造函数,然后执行{}内的内容

 
  

class TestView : View { constructor(context: Context) : super(context) { println("constructor") } constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) }

  1. 主构造函数的代码块(init{} )

// name/age/sex 临时变量可以在构造函数代码块中使用 但不能在方法中使用,要想使用,必须先进行二次接收

 
  

class Test07(name:String,age:Int,sex:Char){ // init 主构造函数的代码块 init { println("主构造函数被调用了: $age") //require 验证是否符合规范 不符合的抛出异常并输出 require(age>0){ "年龄输入不对" } } constructor(name:String):this("王五",55,'男'){ println("次构造函数被调用了: $name") } } fun main() { Test07("李四",88,'女') Test07("二狗") }

  1. 访问修饰符

private protected public internal : Kotlin 特有的。 模块中能访问,跨模块就不能访问了。 例如 Android中的 library/app modual

  1. 伴生对象

 
  

class StringUtils { companion object { fun isEmpty(str: String): Boolean { return "" == str } } } StringUtils.isEmpty("sdfd") java code: StringUtils.Companion.isEmpty("");

  1. 单例类

可使用伴生对象声明单例,是比较推荐的单例写法

 
  

class Single private constructor() { companion object { fun get(): Single { return Holder.instance } } private object Holder { val instance = Single() } }

  1. 动态代理

Kotlin使用动态代理不用像java那么麻烦,kotlin语言原生就支持动态代理,只需要通过by关键字即可

 
  

interface Animal { fun bark() } class Dog : Animal { override fun bark() { println("Wang") } } class Zoo(animal: Animal) : Animal by animal fun main(args: Array) { Zoo(Dog()).bark() } // 如果在Zoo 中再实现一下 bark(), 则就会用自己实现的 class Zoo(animal: Animal) : Animal by animal { override fun bark() { println("Zoo") } }

Kotlin中的动态代理编译后会转成静态代理,比Java的动态代理(反射实现)效率高。

  1. Kotlin 特有的类

  1. 数据类

 
  

data class User(var id: Int, var name: String) public final getter()/setter() toString() hashCode() equals() copy()

  1. 枚举类

 
  

enum class Command { A, B, C, D } fun exec(command: Command) = when (command) { Command.A -> { } Command.B -> { } Command.C -> { } Command.D -> { } }

  1. 密闭类

Kotlin中一般不使用枚举类,而是使用更加强大的枚举类 --- 密闭类

 
  

sealed class SuperCommand { object A : SuperCommand() object B : SuperCommand() object C : SuperCommand() object D : SuperCommand() class E : SuperCommand() // 密闭类可以有子类,但必须与密闭类写在一个同文件中 } fun exec(superCommand: SuperCommand) = when (superCommand) { SuperCommand.A -> { } //... is SuperCommand.E -> { } }

你可能感兴趣的:(开发分享,android,java,kotlin)