Kotlin入门,一篇文章就够了

Android为啥要从Java转向Kotlin Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源。苹果公司已经在用Swift语言替代Object-C语言,Google也找到了替代Java的语言,也就是JetBrains公司(Android Studio也是用该公司的Intelli J改的)主推的Kotlin。现在将kotlin作为了编写Android的官方语言,而后会有越来越多的项目使用Kotlin。Kotlin有了强有力的亲爸JetBrains公司和Google这个干爸,自然被捧在手心了。
Kotlin在编写代码时有如下优势:

  • 代码简洁高效
  • Android Jetpack 与其他库中的 Kotlin 支持
  • 可与 Java 的一起使用
  • 空指针安全
同样,kotlin支持函数式编程、支持lambda表达式、流式API...,此处略去一万字。总之,Java是上世纪的编程语言了,当你学过了Kotlin之后 ,你会发现,之前写过那么多的代码都是在浪费生命。
语法基础
变量
var age: Int = 0 var num = 20 val TYPE: Int = 100 var name: String = ""

写法形如:var str: String
用var或val声明,前面是参数名,后面是参数的类型,中间用:分割
var即英文“variable”的意思,声明成一个可变变量。val即英文“value”的意思,申明的是一个不可变变量,对应的java里面的final。
kotlin中有优秀的类推导机制,age声明了变量类型,num没有声明变量类型,但是依然可以通过,是由Kotlin自动推导了类型。
常量 const
如果只读属性的值在编译期是已知的,那么可以使用 const 修饰符将其标记为编译期常量,相当于java中的public static final修饰。
空指针检查 在Kotlin里,可以用“?”表示可以为空,也可以用“!!”表示不可以为空。
给变量加上?标识,会通告所有使用该变量的地方,必须给出为空的补救措施。
var info: String? = nullprintln(info?.length)//第一种补救:如果info为null,就不执行后面的.length代码println(info!!.length)//第二种补救:这里如果为null,我自己负责info,会报出空指针,这种处理需慎用if (info != null) {//第三种补救措施,如下这种同java写法 println(info.length) }println(info?.length ?: "空数据")//第四种补救措施,如果真的为null,则改为返回"空数据"

第二个检查方式是let函数,?.当然能解决大部分问题,但是user每使用一次?.相当于都加上了代码if(user != null),实际上在同一个函数中,我们只需要做一次非空判断就行了,这就是我们的let函数的作用,在代码块内容用it代替该对象。
user.let { it.login() it.logout() }

延迟初始化 在kotlin中,不会给变量默认初始化,必须初始化,也不能设置null。比如如下设置null为默认值,或者不设默认值,都是编译不通过的:
var name: String = null var age: Int

这种情况我们只好用?可为空标识,那使用的时候就每次都要处理一下。那么怎么解决这种不想或者不能设置默认值的情况呢?用延迟初始化!
  • lateinit
    想在类体中引用该属性时避免空检测,用可用lateinit关键字。
var user: User? = null lateinit var user: User

lateinit 不能用来修饰基本数据类型,因为基本类型的属性在类加载后的准备阶段都会被初始化为默认值。
lateinit不能修饰val变量,只能修饰可变的属性
  • by lazy
    Kotlin提供了懒加载lazy机制,在懒加载机制里,变量只有在第一次被调用时,才会初始化。lazy只适用于val对象,对于var对象,需要使用lateinit。
private val textview: TextView by lazy { findViewById(R.id.tv_content) as TextView }

可见性修饰符 在 Kotlin 中有这四个可见性修饰符:private、 protected、 internal 和 public。 如果没有显式指定修饰符的话,默认可见性是 public。
internal:在本模块内可见
字符串拼接 将变量拼接在字符串之内,用${}来包裹变量即可
fun StringFormat(title: String) = { "这里是拼接字符串${title}" }

字符串自动换行:
val content = """ 哈哈哈哈 呵呵呵呵 嘿嘿嘿嘿 """.trimIndent()

值比较、赋值:
println(name1.equals(name2))//同java的equalsprintln(name1 == name2)//同equals作用,比较值的相等,这里为trueprintln(name1 === name2)//比较地址是否相等,即比较是否为同一个对象,这里为false

将条件判断的结果赋值:
val num1 = 100 val num2 = 101 val max = if (num1 > num2) num1 else num2

关键字
when 用when关键字代替java中的switch使用,when作为判断,条件可为任意类型
fun whenUse(obj: Any, type: Int) { when(obj) { 1 -> "" in 2..5 -> "" is String -> "" else -> "" } }

将when的返回值直接使用起来赋值:
var result = when(type) { 1 -> "1" 2 -> "2" 3 -> "3" else -> "4" }

Any java中所有类的父类是Object,而Kotlin中所有类的父类为Any。
object Kotlin中没有大写的Object了,而是有小写的object,表示单例。
class SingleTon { object Holder { var instance = SingleTon() } }

is Kotlin中用is代码java中的instanceOf 来判断类型
fun charge() { var type = "" if (type is String) {//instanceOf} }

in使用
  • in来检查一个值是否在一个区间内
fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'//检查字符是否为字母

  • 检查list中是否有元素name
if(name in list) { }

init 主构造函数里不能写代码,那我们怎么初始化这个类的代码呢?Kotlin则是提供了初始化模块,基本上就是用init修饰符修饰一个{},在类初始化时执行这段代码。
class User() { init {} }

数组
创建数组
var names = arrayOf("小王", "小花", "小红", "小明")var ages = arrayOf(22, 19, 18)var array = arrayOfNulls(5)//创建空数组 array.set(1, "哈哈")//赋值

数组遍历
for (i in 1..5 step 1) {//跳过第1步遍历}for (i in 0..names.size-1) {//遍历names数组,相当于java里for (int i=0:i//带position的遍历}

in的用法:val num = 1..10,表示变量num是一个[1,10]的区间。
step表步长,表示遍历间隔的个数。
类与对象
类构造函数 在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。
class User constructor(name: String, age: Int, id: Int)class User(name: String, age: Int, id: Int)

加入次构造函数:
class User(name: String) { //主构造函数constructor(name: String, age: Int, id: Int): this(name) {//次构造函数,必须去调用主构造}constructor(): this("暂无名字") { } }

分别调用三个构造函数:
User()//次构造 User("小明")//主构造 User("小明", 18, 1)//次构造

函数 示例:
fun function(params: String): Int {}

  • params: String 函数参数
  • fun function(params: String) 无返回值函数
  • fun function(params: String): Int 有返回值函数,返回值类型为Int
  • Kotlin的函数可以声明为toplevel也就是跟class一个级别,也就是说不必非放在类里面
  • 如果一个函数只有一行代码时,kotlin允许我们直接这样写,直接省略函数体
    ,如:
fun getAddressB(id: Int, name: String) = { "北京" }fun getAddressC(id: Int, name: String) = "上海"//类型自动推导

返回值类型为Unit,表示为void返回类型,在函数无返回时,一般不写Unit。
fun getAddressE(id: Int, name: String): Unit {}fun getAddressE(id: Int, name: String) {}

多参数函数写法:
fun setDatas(vararg value: Int) { for (i in value) { println(i) } }Test().setDatas(0, 1, 2)

函数的默认参数值 声明函数变量时,直接给参数设置默认值,如果调用函数时对应参数缺省,那么该参数就是默认值。而在java中实现默认参数值方法则是需要自己写多个重构方法。
fun createUser(name: String = "小明", age: Int = 20, id: Int = 1) {}createUser() createUser("小王") createUser("小红",18) createUser("小李", 25, 2)

创建对象 Kotlin中创建对象不再需要关键字new了,直接创建对象:
var user = User()

继承 在Kotlin中的类和方法默认是不可以被继承的,需要加上关键字open,才允许被继承。继承用":"表示,类和接口的继承都用":",类需要加()。
class VipUser : User(), Use {}open class User {}interface Use {}

内部类
class OuterClass {val count = 100//这个叫嵌套类,不是内部类,拿不到外部类的count属性 class InterClass {fun show() { //println(count) } }//加上inner声明,就为内部类,可以拿到count属性 inner class InterClass2 {fun show() { println(count) } }}

数据类 即为我们通常使用的bean类,一般在定义数据类的时候,我们需要手动实现这个类的equals()、hashcode()、toString()等方法,这些方法是必要的。但是加上data关键字后,该类会自动生成这些方法。
data class User(var name: String) {}

单例类 【Kotlin入门,一篇文章就够了】在java中,单例的写法需要自己手动实现,比如用懒汉式还是饿汉式。但是在Kotlin中单例就非常简化了,只需要将class替换成object就可以了。
object SingleTonClass {var params: String? = nullfun function() {} }SingleTonClass.function()SingleTonClass.params

使用单例时不需要再获取instance实例对象了,Kotlin已经在内部帮我们创建了一个单例的实例,直接使用类名调用它的属性和方法。
compaion object(伴生对象) 在java中static表静态变量,kotlin中取消了static,用compaion object来代替它的用法。
class SingleTon {object Holder { val instance = SingleTon() }companion object { fun getInstance() = Holder.instance } }

最后:将现有Java文件转换为Kotlin文件 我们可以将现有Java文件代码转换为Kotlin文件代码,而实现从java往kotlin上转移。可以针对单个文件,某个包,某个module,或者整个项目转为kotlin文件。
转换完成之后可能会有少量语法错误,需要手动修改一下。
Kotlin入门,一篇文章就够了
文章图片
将kotlin代码转为java 在Tools->Kotlin->show Kotlin ByteCode,点击Decompile转回类似Java代码。

Kotlin入门,一篇文章就够了
文章图片

    推荐阅读