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 的一起使用
- 空指针安全
语法基础
变量
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代码转为java 在Tools->Kotlin->show Kotlin ByteCode,点击Decompile转回类似Java代码。
文章图片
推荐阅读
- 由伐木工引发的陈述
- 随笔一篇
- android防止连续点击的简单实现(kotlin)
- 我为什么写不出一篇读书分享稿()
- typeScript入门基础介绍
- 2018-06-29|2018-06-29 这是我的第一篇文章 markdown
- 《如何写出一篇好文章》之赠送礼物的训练
- 为了女儿,我尝试画画——DIY绘本之《一支铅笔的梦想》(绘画小白的第一篇作品)
- retrofit2-kotlin-coroutines-adapter|retrofit2-kotlin-coroutines-adapter 超时引起的崩溃
- Kotlin泛型的高级特性(六)