上面代码对应的 java 实现逻辑如下:
TestClass testClass = null;
if (testClass != null) {
testClass.func();
}
System.out.println(“done”)
!!.
在 kotlin 中的使用案例如下:
val testClass: TestClass? = null
testClass!!.func()
println “done” //当testClass为空则抛出异常,这里没机会执行
上面代码对应的 java 实现逻辑如下:
TestClass testClass = null;
if (testClass != null) {
testClass.func();
} else {
throw new NullPointerException();
}
System.out.println(“done”)
Elvis 表达式?:
很像 java 的三目运算符,但又不一样,其使用案例如下:
//当 name 不为 null 则返回 null 给 str,当 name 为 null 则返回 default 给 str
val str = name ?: “default”
as
被用做类型转换或者重取别名,当用作取别名时案例如下:
//包及导入特性小节演示过了
//指定导入别名
import cn.yan.test2.funcTest as selfFuncTest
当用作类型转换时,as
用于执行引用类型的显式类型转换,如果要转换的类型与指定的类型兼容则成功执行,如果类型不兼容则会抛出转换异常;当使用as?
运算符进行类型转换,如果要转换的类型与指定的类型兼容则成功执行,如果类型不兼容则返回 null。在 kotlin 中,父类型是禁止转换为子类型的,请务必注意。
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
open class Fruit
open class Apple(name: String) : Fruit()
val fruit = Fruit()
//抛出 java.lang.ClassCastException 异常
println(fruit as Apple)
//打印为 null,安全的类型转换
println(fruit as? Apple)
kotlin 类型Unit
、Nothing
和Nothing?
、Any
和Any?
区分
kotlin 中 Unit 类型与 java 中 void 的功能基本相似。如下是 kotlin 源码中 Unit 的源码:
//Unit 类型是一个 object 对象类型
public object Unit {
//toString 函数返回值
override fun toString() = “kotlin.Unit”
}
在 kotlin 中,当一个函数没有返回值时,我们用 Unit 来表示,而不是 null;大多数时候我们不需要显示地返回 Unit,或者声明一个函数的返回值是 Unit,编译器会自动推断它。跟 kotlin 的其他类型一样,Unit 的基类型是 Any。如果是一个可空的Unit?
则父类型是Any?
。Any?
是 Any 的超集,Any?
是 kotlin 类型层次的最顶端。
fun main() {
val unit = testUnit()
println(unit is Unit) //true
println(unit is Any) //true
println(unit is Unit?) //true
println(unit is Any?) //true
val unitNullable = testUnitNullable()
println(unitNullable is Unit) //false
println(unitNullable is Any) //false
println(unitNullable is Unit?) //true
println(unitNullable is Any?) //true
}
fun testUnit(): Unit {}
fun testUnitNullable(): Unit? { return null }
我们知道,在 java 中 void 不能是变量的类型,也不能作为值打印输出,java 提供了一个包装类 Void(void 的自动装箱类型),如果我们想让一个方法的返回类型永远是 null,则可以把返回类型定义为这个大写的 Void 类型。
java 中的这个 Void 类型对应 kotlin 的类型就是Nothing?
,在 kotlin 中可以理解为不可达,即不返回或者返回不可访问类型,是一种约定,Nothing 的类源码如下:
//外界无法创建 Nothing 实例
public class Nothing private constructor()
在 kotlin 中 throw 表达式的返回值就是 Nothing 类型的,表示了一种不可达(因为 throw 表达式执行完毕后就异常了,自然也就是不可达后续流程了),所以如果一个函数返回值是 Nothing,那么这个函数永远不会有返回值。譬如如下场景:
//因为 pick 永远不会反回值,而是直接抛出了异常,这个时候可以用 Nothing 作为 pick 函数的返回值
fun pick(index: Int): Nothing {
throw Exception()
}
所以 Unit 与 Nothing 的区别是,Unit 类型表达式计算结果返回值是 Unit,Nothing 类型表达式计算结果永远是不会反回的。
此外Nothing?
可以只包含一个值 null,Nothing?
唯一允许的值是 null,可被用作任何可空类型的空引用。譬如如下场景:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
val test = null //编译器只能推断出类型为 Nothing?,空或者不可达类型
println(test is Nothing?) //true
val test1 = listOf(null) //编译器推断的类型为 List<Nothing?>
与 java 不同的是,kotlin 的变量类型可以是类似下面这样的(其实 groovy 也有类似部分特性):
//有返回值原始写法
fun count(arg1: Int, arg2: Int): Int {
return arg1 + arg2
}
//一行表达式简写
fun count2(arg1: Int, arg2: Int): Int = arg1 + arg2
//自动类型推断简写
fun count3(arg1: Int, arg2: Int) = arg1 + arg2
//无返回值原始写法
fun printCom(arg1: Int, arg2: Int): Unit {
println(“$arg1 — $arg2”)
}
//一行表达式简写
fun printCom1(arg1: Int, arg2: Int) = println(“$arg1 — $arg2”)
//自动类型推断简写
fun printCom2(arg1: Int, arg2: Int) {
println(“$arg1 — $arg2”)
}
java 中的 if 语句仅仅只能当作语句使用,而 kotlin 中 if 即可以当语句使用,还可以当作表达式使用,譬如:
fun main() {
var x = 10
var y = 20
var max: Int
var min: Int
//标准写法
if (x > y) {
min = y
max = x
} else {
min = x
max = y
}
//简写1,if 可以当作表达式
min = if (x > y) y else x
//简写2,if 可以当作表达式,如果 if 后面是代码块则代码块中最后一行返回值返回
max = if (x > y) {
println(“x > y”)
x
} else {
println(“x <= y”)
y
}
}
我们知道,java 包名必须与磁盘目录一致,kotlin 包名没有这个限制,但是建议尽量一致,方便维护阅读。使用其他包中非 class 中定义的方法时可以直接 import 导入包,譬如:
//Test1.kt 文件使用 Test2.kt 文件
package cn.yan.test
import cn.yan.test2.funcTest
funcTest(1, 2) //调用 test2 包中的 funcTest 方法
还可以指定别名使用:
package cn.yan.test
//指定导入别名
import cn.yan.test2.funcTest as selfFuncTest
selfFuncTest(1, 2) //调用 test2 包中的 funcTest 方法
kotlin 中 for 循环遍历语法与 java 有比较大的差异,具体如下:
fun main() {
//IntArray 在 jvm 中表示的是 int[] 类型,可以看其注释得知
var array: IntArray = intArrayOf(1, 2, 3)
//遍历数组元素
for (item in array) {
println(item)
}
//遍历数组下标索引
for (index in array.indices) {
println(“array[ i n d e x ] = index]= index]={array[index]}”)
}
//遍历索引及元素
for ((index1, value1) in array.withIndex()) {
println(“-array[ i n d e x 1 ] = index1]= index1]=value1”)
}
}
此关键字相对 java 来说是 kotlin 新增的,可以当作 switch 来使用,其 case 没有 java 常量类型限制,可以是任意表达式,如下:
fun testWhen() {
println(convertStr(“he”)) //other
println(convertStr(“h”)) //hello
var tmp = 12
var ret = when(tmp) {
in 0…20 -> “match 0…20”
30, 31, 32 -> “31, 32, 30”
33 -> “match 33”
else -> “other”
}
println(ret)
}
//简写
fun convertStr(str: String): String {
return when(str) {
“h” -> “hello”
“w” -> “word”
else -> “other”
}
}
//继续简写
fun convertStr1(str: String) = when(str) {
“h” -> “hello”
“w” -> “word”
else -> “other”
}
range 也是 kotlin 相对于 java 新增加的东西,比较好用,具体如下:
fun testRange() {
val a = 5
val b = 10
//… 左右都是闭合区间,… 本质是 rangeTo 方法
if (a in 2…b) {
println(“range matched”)
}
if (a !in 2…b) {
println(“range not matched”)
}
for (i in 2…10) {
println(“----$i”)
}
for (i in 2.rangeTo(10)) {
println(“—x—$i”)
}
//step 是中缀表达式,遍历2到10,每次跳2个index
for (i in 2…10 step 2) {
println(“step----$i”)
}
//逆序遍历
for (i in 10 downTo 2 step 2) {
println(“downTo-step—$i”)
}
}
range 也有他的坑,具体如下案例:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
fun testRun() {
//打印输出,range 0…2表示左右闭合区间
if (1 in 0…2) {
println(“1 in the [0, 2]”)
}
//遍历输出 1、2
for (i in 1…2) {
println(“for loop $i”)
}
//不输出任何东西,因为 range 默认按照升序查找,左区间是 4,右侧小于 3,等价于 for(int i=4; i<3; i++)
for (i in 4…3) {
println(“for loop $i”)
}
//遍历输出4、3
for (i in 4 downTo 3) {
println(“for loop current $i”)
}
//遍历跨间隔输出 6、4、2、0,step 参数必须是正数
for (i in 6 downTo 0 step 2) {
println(“for loop step $i”)
}
//遍历输出 0、1,左闭右开区间
for (i in 0 until 2) {
println(“for loop until $i”)
}
}
关于函数式编程,对于 java 来说有很多框架的选择,譬如 rxjava 等等,但是对于 kotlin 来说,其天生支持这一能力,譬如:
fun testList() {
var array = listOf(“aa”, “bbb”, “c”, “dddd”, “eeeee”)
//如果bbb在列表则打印
when {
“bbb” in array -> println(“bbb in the list”)
}
//函数式编程实现:找出长度大于3,转换为大写,排序后逐个输出
array.filter { it.length >= 3 }.map { it.toUpperCase() }.sorted().forEach { println(it) }
}
这个特性很像 ES6 的解构赋值,但又有自己的注意事项规则,譬如,kotlin 中默认能被解构的类必须是 data 类。如下:
//data数据类支持解构
data class RetValue(val statusCode: Int, val message: String)
//kotlin 提供的内置两值返回解构类型 Pair,也有三值的类型 Triple
fun test1(): Pair<Int, String> = Pair(404, “NotFound”)
/**
调用结果:
code=200, msg=ok
code1=404, msg1=NotFound
*/
fun testRun() {
//解构声明
val (code, msg) = RetValue(200, “ok”)
println(“code= c o d e , m s g = code, msg= code,msg=msg”)
val (code1, msg1) = test1()
println(“code1= c o d e 1 , m s g 1 = code1, msg1= code1,msg1=msg1”)
}
解构声明与集合的应用实例:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
后续会持续更新**
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-RfZAcpsc-1712797680652)]
总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
[外链图片转存中…(img-MWo77AyO-1712797680652)]
[外链图片转存中…(img-asYouitU-1712797680653)]
[外链图片转存中…(img-RJ3u6Q4x-1712797680653)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-l6QdmJvd-1712797680653)]