Kotlin 基础学习
学!
原文:https://blog.csdn.net/CrazyApes/article/details/122091459
文章目录
- Kotlin
- 线上编写
- 变量
- lateinit延迟初始化
- 空安全
- 比较==,===,equals
- for循环
- when
- 三目运算
- DataClasses
- 静态内部类实现
- 扩展属性
- Java调用顶级函数
- synchroized
- volatile
- wait,notify 与 notifyAll
- thread
Kotlin
只要学,啥时候都不晚!
这里主要介绍从java转到kotlin中一些常见的基础学习
读完这篇文章
你应该能很快适应kotlin的开发节奏了
内容不断补充中…
点击标题头可以直达文档,因为本文只简介,想了解更详细具体内容的可以直接看原文档
线上编写
Kotlin官网提供了 PlayGround 供大家线上尝试
地址:https://play.kotlinlang.org/
哈哈,没有环境的小伙伴或者只是想尝试的小伙伴,可以使用线上编写。
比如,我写博客的很多东西其实都是在线上试的,哈哈。
变量
// 各种示例
var name = "CrazyApes"
name = "CrazyApe"var myName : String = "CrazyApes"
var age : Int = 99
var number = 3.1
var floatNumber val value = "不可变"class Address {var name: String = "Holmes, Sherlock"var street: String = "Baker"var city: String = "London"var state: String? = nullvar zip: String = "123456"
}
lateinit延迟初始化
- 必须初始化后才可以使用,否则会出异常
kotlin.UninitializedPropertyAccessException: lateinit property value has not been initialized - lateinit 声明后不允许赋值为 null, 加问号也不行。
所以,如以下示例代码,findViewById返回为null会崩,当然,我们本意也不希望它空,但是这个是要注意你如果声明的是一些需要用的变量的话 ,需要注意此类问题。
private lateinit var mBaseView : View
private lateinit var mData : String
private var mNullableStr : String? = null// 例如 onCreate
onCreate(...){mBaseView = findViewById(R.id.baseView)// 未初始化 UninitializedPropertyAccessExceptionprint(mData)// 可检查if (mData.isInitialized)print(mData)// 如果return了null 就 NullPointerExceptionmData = getIntent.getExtraString("MaybeNull")mNullableStr = getIntent.getExtraString("MaybeNull")val length = mNullableStr?.length // 如果null ,return nullval length1 = mNullableStr?.length ?: -1; // 如果null ,return -1 有点像三目的感觉
}
空安全
kotlin 是空安全的语言
意思就是你要是没显示声明可以为空,只要遇到了空就报空指针。
- ?. 安全的调用方式
如果是 null 不会执行后续的操作,直接返回 null - ?:
如果是 null,则执行冒号后面的部分 - !!
非空断言运算符,若果是null,就NullPointerException
private var mNullableStr : String? = null
private var mNullableList : List<Int?> ?= nullfun testForNullSafe(){mNullableStr = getIntent.getExtraString("MaybeNull")val length = mNullableStr?.length // 如果null ,return nullval length1 = mNullableStr?.length ?: -1; // 如果null ,return -1 有点像三目的感觉val length2 = mNullableStr!!.length; // 如果null ,就 NullPointerExceptionmNullableList = listOf(1, 2, null, 4)
}
比较==,===,equals
- == 结构值相等
类似Java中equals - === 和 !== 内存引用相等和不等
类似Java中原来的 == 和 !=
注意:
1.如果是基类略等于==,比如Int啥的
2. Float 和 Double 比较特殊。
某些特殊情况下,比如,如果当操作数不是静态类型化为浮点数,调用的就会是对应的equals方法和compareTo方法,会导致以下结果出现。
a). -0.0 比 0.0小。
b). NaN被认为与自身相等。
c). NaN比无穷大都大。
大家可以通过以下代码验证其结果性。
// 静态化浮点数
print(-0.0f == 0.0f) // true
print(Float.NaN == Float.NaN) // false
print(Float.NaN > Float.POSITIVE_INFINITY) // false // 非静态化为浮点数 例如 :Any
val numZero1 : Any = -0.0f
val numZero2 : Any = 0.0f
println(numZero1 == numZero2) // false 通过 equals 比较// Comparable
val numZero3 : Comparable<Float> = -0.0f
val numZero4 : Float = 0.0f
println(numZero1 < numZero2) // true 通过 compareTo 比较// NaN
val firstNaN : Any = Float.NaN
val secondNaN = Float.NaN
println(firstNaN == secondNaN) // true 通过 equals 比较// 无穷
val compareNaN : Comparable<Float> = Float.NaN
val positiveInfinity = Float.POSITIVE_INFINITY // 正无穷
println(compareNaN > positiveInfinity) // true 通过 compareTo 比较
for循环
有许多很好用的新函数
比如:
范围 rangeTo : 1…100 代表1到100
步长 step : 1…100 step 2 代表1,3,5,7…97,99
降序 downTo: 100 downTo 1 代表 100,99,98…1 ,其实就是步长为-1
还有很多,直接看例子吧。
fun main() {for (i in 1..100) // 遍历 1 到 100println(i) // 1,2,3,4,5,... 99,100for (i in 100 downTo 1) // 遍历 100 到 1println(i) // 100,99,98...2,1for (i in 100 downTo 1 step 2) // 遍历 100 到 1 步长为 2println(i) // 100,98,96....2for (i in 1 until 100) // 遍历 1 到 100 [1,100) 不包括100println(i) // 1,2,3,4 ... 98,99val arr = arrayOf("a", "b", "c", "d", "e")for (item in arr) // 遍历数组println(item) // a,b,c,d,efor (i in arr.indices) // 遍历下标println(i) // 0,1,2,3,4for ((index, value) in arr.withIndex()) // 获取下标及值println("the element at $index is $value") // ... 0 is a,... 1 is b,... 2 is carr.reverse() // 反转数组for (item in arr) // 遍历反转后的数组println(item) // e,d,c,b,a
}
when
val str = when (index) {0 -> "Empty"in 1..9 -> "Number"in 10..100 -> "under 100"else -> "Other"}when {index == 0 -> a + bindex in 1..9 -> a - bindex is Number -> a = bindex is String -> a = 0index == "3" -> a = 3else -> a / b}val num = (1..999).random() // 随机产生 1-999中的任何一个val numStr = when (num) {in 1..9 -> "00$num" // 001,002,003...009in 10..99 -> "0$num" // 010,011,012...099else -> "$num" // 100...999}println(numStr)
三目运算
Kotlin没有标准的三目运算符,所以都换成 if…else 了
搭配Lambda之后发现也没啥区别了。
甚至还更灵活了。
复杂一些的可以直接考虑用 when
fun main() {val a = 1val temp = if (a == 1) 2 else aprintln(temp) // temp = 2// view view.visibility = if (view.visibility == View.VISIBLE) View.GONE else View.VISIBLE }
DataClasses
主构造函数必须要至少有一个参数
在Java虚拟机里,如果生成的类需要有一个无参数的构造函数,所有属性的默认值必须有一个具体的值主构造函数中的所有参数必须被标记为val或者var
数据类不能有以下修饰符:abstract,inner,open,sealed
// 常见方式
data class NetData(val state: Int,val data: Data
) {// 等同于java静态内部类 static class// kotlin 内部类需 加 inner 标识// 没加inner 就是静态内部类data class Data(val name: String,val age: Int,val sex: Int)
}// 需要无参构造的事例
data class User(val name: String = "",val age: Int = 0)
静态内部类实现
kotlin 有专门的 inner 标识非静态内部类
没有添加 inner 标识则默认为静态内部类使用
data class NetData(val state: Int,val data: Data
) {// 等同于java静态内部类 static class// kotlin 内部类需 加 inner 标识// 没加inner 就是静态内部类class Data(val name: String,val age: Int,val sex: Int)
}
扩展属性
扩展属性是个好东西啊。
比如我可以快速的转换dp,或者sp操作等
/*** 扩展属性,dp* dp to px*/
val Number.dp: Floatget() = android.util.TypedValue.applyDimension(android.util.TypedValue.COMPLEX_UNIT_DIP,this.toFloat(),Resources.getSystem().displayMetrics)/*** 扩展属性,sp* sp to px*/
val Number.sp: Floatget() = android.util.TypedValue.applyDimension(android.util.TypedValue.COMPLEX_UNIT_SP,this.toFloat(),Resources.getSystem().displayMetrics)fun main() {// 3 dp to px println(3.dp) // print Floatprintln(3.dp.toInt) // print Int
}
Java调用顶级函数
可以使用 @file:JvmName(JavaName)
标注
// DemoTempUtil.kt
@file:JvmName("TempUtil")package com.crazy.demo.tempfun DemoActivity.demoFuntion(title:String):Boolean {return title == "demo"
}// Java DemoActivityprivate void checkTitle() {TempUtil.demoFuntion(this,title);
}
synchroized
kotlin 没有 synchroized 关键字
- 同步方法
但是可以使用@Synchronized
注解。
这个注解和Java中的synchronized有同样的效果:它将把JVM方法标记为同步。
@Synchronized fun synchronizedMethod() {println("synchronized method:${Thread.currentThread()}")
}
- 同步代码块
此外,kotlin还有自己的synchronized()
方法用来锁定代码块。
fun synchronizedBlock() {synchronized(lock){println("synchronized block")}
}
可以看一下源码实现
( kotlin version : 1.6.0 )
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("StandardKt")
package kotlinimport kotlin.contracts.*
import kotlin.jvm.internal.unsafe.*/*** Executes the given function [block] while holding the monitor of the given object [lock].*/
@kotlin.internal.InlineOnly
public inline fun <R> synchronized(lock: Any, block: () -> R): R {contract {callsInPlace(block, InvocationKind.EXACTLY_ONCE)}@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "INVISIBLE_MEMBER")monitorEnter(lock)try {return block()}finally {@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "INVISIBLE_MEMBER")monitorExit(lock)}
}
volatile
同样的,kotlin 也没有 volatile 关键字
同样可以使用注解 @volatile
的方式使用。
@Volatile private var running = false
wait,notify 与 notifyAll
在kotlin里面,每一个类都是从 Any
继承过来的,但是 Any
并没有声明wait()
,notify()
和notifyAll()
方法。
但是你能用 java.lang.Object
的实例作为 lock
,并且调用相关的方法。
private val lock = java.lang.Object()fun produce() = synchronized(lock) {while (items >= maxItems) {lock.wait()}Thread.sleep(rand.nextInt(100).toLong())items++println("Produced, count is $items: ${Thread.currentThread()}")lock.notifyAll()
}fun consume() = synchronized(lock) {while (items <= 0) {lock.wait()}Thread.sleep(rand.nextInt(100).toLong())items--println("Consumed, count is $items: ${Thread.currentThread()}")lock.notifyAll()
}
thread
kotlin 有封装好的 thread
方法
// 方法一
// kotlin 方法
thread(start=true) {println("running from thread():${Thread.currentThread()}")
}// 方法二
object : Thread() { override fun run() {println("running from Thread: ${Thread.currentThread()}")}
}.start()// 方法三
Thread({ println("running from lambda: ${Thread.currentThread()}")
}).start()
这里仅贴一下源码。方便大家查看
@file:JvmName("ThreadsKt")
package kotlin.concurrent/*** Creates a thread that runs the specified [block] of code.** @param start if `true`, the thread is immediately started.* @param isDaemon if `true`, the thread is created as a daemon thread. The Java Virtual Machine exits when* the only threads running are all daemon threads.* @param contextClassLoader the class loader to use for loading classes and resources in this thread.* @param name the name of the thread.* @param priority the priority of the thread.*/
public fun thread(start: Boolean = true,isDaemon: Boolean = false,contextClassLoader: ClassLoader? = null,name: String? = null,priority: Int = -1,block: () -> Unit
): Thread {val thread = object : Thread() {public override fun run() {block()}}if (isDaemon)thread.isDaemon = trueif (priority > 0)thread.priority = priorityif (name != null)thread.name = nameif (contextClassLoader != null)thread.contextClassLoader = contextClassLoaderif (start)thread.start()return thread
}
Kotlin 基础学习相关推荐
- Kotlin基础学习(1)
Kotlin基础学习(1) 本文主要讲解kotlin的部分基础知识,并不是全部基础. 提示:纯属个人理解,如有理解错误,欢迎留言指正批评. 一.Null检查机制 kotlin对于声明可为空的参数,使用 ...
- Kotlin基础学习(一)—— Kotlin 简介
一.背景 2017年 的Google I/O大会上,Kotlin称为官方的Android开发语言. 发明公司:JetBrains(最负盛名的IDE创造者,包括Android Studio.Intell ...
- Kotlin基础学习 17
目录 1.Kotlin语言的过滤函数-filter 2.Kotlin语言的合并函数-zip 3.Kotlin语言的函数式编程 4.Kotlin语言的互操作性与可空性 5.单例模式 6.注解@Jvmna ...
- Android Kotlin基础学习 - 接口
文章目录 背景 接口定义 接口实现 实例 接口中的属性 实例 函数重写 实例 背景 学习,记录分享,坚持开源! 接口定义 Kotlin 接口与 Java 8 类似,使用 interface 关键字定义 ...
- Kotlin基础学习08
目录 1.Kotlin语言的takeUnless内置函数 2.Kotlin语言的List创建与元素获取学习 3.Kotlin语言的可变List集合学习 4.Kotlin语言的mutator学习 5.K ...
- Kotlin基础学习 09
目录 1.Kotlin语中的Map的创建 2.Kotlin语中的读取Map的值 3.Kotlin语言遍历Map学习 4.Kotlin语言的可变Map集合学习 5.Kotlin语言定义类与field关键 ...
- Kotlin基础学习 --- 内置函数apply、let
apply内置函数 fun main(){val buffer = "i am buffer "//常规方式println("buffer的字符长度是:${buffer. ...
- Kotlin基础学习(十九)—— 解构声明和组件函数
解构声明的作用:展开单个复合值. 一个解构声明看起来像一个普通的变量声明,但它在括号中有多个变量 1.解构声明举例: val p = Point(10,20) //Point 是数据类 val(x, ...
- Kotlin 基础学习06
目录 1.Kotlin语法中异常处理与自定义异常特点 2.Kotlin语言的先决条件函数 3.Kotlin语言的substring 4.Kotlin语言的split操作 5.Kotlin语言的repl ...
最新文章
- linux 排程命令,Ubuntu 排程設定 :Crontab 排程使用教學
- MySQL—06—数据库三大范式
- nodejs安装及环境配置_nodeJS安装和环境变量的配置
- 使用腾讯云短信服务技术出现FailedOperation.TemplateIncorrectOrUnapproved
- ASP.NET MVC5使用AjaxHelp
- 非中国服务器的时区问题
- Chrome下的语音控制框架MyVoix.js使用篇(二)
- 谷歌为什登不上去github_同声传译被攻陷!谷歌发布Translatotron直接语音翻译系统...
- Java核心技术 基础知识网盘下载
- 西门子/软件/S7-300.400/simatic step 7 v5.5 sp4 chinese
- python和前端哪个好_web前端和python学哪个出来工资高?
- 服务器硬盘raid方案,服务器RAID磁盘阵列经验总结
- 服务案例|TAS系统安全深度威胁发现案例
- 继电器控制电路原理解析说明
- TensorFlow Ranking框架在海外推荐业务中的实践与应用
- Matebook xpro2019指纹驱动不可用
- UICollectionView 适配 iPhone 7 Plus
- FFmpeg c++ 报错合集
- Codeforces Round #705 (Div. 2) A-D
- TikTok运营工具大全(必收藏)