Kotlin修炼指南(三),阿里P8面试官都说太详细了

这种方式比Java节省了太多的代码,所以Kotlin中不再需要三目表达式了,直接通过if/else即可。

fun max(a: Int, b: Int) = if (a > b) a else b

延迟初始化

在Kotlin中,成员变量的值被严格区分可空和非可空,其中非可空的变量值,要么在声明的时候进行初始化,要么通过延迟加载的方式进行初始化,一般来说,有两种方式来进行延迟加载。

lazy

通过lazy函数,可以实现在首次使用到的时候才去实例化。

private val xxxxFragment by lazy {
XXXXFragment().apply {
arguments = Bundle().apply {
}
}
}

lateinit

通过lateinit,自己控制变量的初始化。

private lateinit var iv: ImageView

这两种方式各有各的使用场景:

  • by lazy 修饰val的变量
  • lateinit 修饰var的变量,且变量是非空的类型

data class

data class是Kotlin中一个用来生成模板代码的语法糖,在Java中,定义的实体类,通常会有很多的模板代码,大部分情况下,我们都是通过一个工具插件来生成,而在Kotlin中,则更加简单。

第一种方式实际上是Kotlin对构造函数的优化,省略了构造函数的实体,直接通过参数声明的方式进行了创建。

// Kotlin会为类的参数自动实现get set方法
class User(val name: String, val age: Int, val gender: Int, var address: String)

第二种方式则是借助data关键字,生成Kotlin中定义好的实体类。

// 用data关键词来声明一个数据类,除了会自动实现get set,同时还会自动生成equals hashcode toString
data class User(val name: String, val age: Int, val gender: Int, var address: String)

object

object在Kotlin中是一个比较难理解的概念,和Java中的Object完全不同,后面会有单独的文章来介绍object,这里先简单的看下Kotlin通过object提供的语法糖。

object,其实可以把它理解成:定义一个类并创建该类的一个实例。

所以object的一个功能,就是快速创建一个单例模式。

例如在代码中经常写的:

object ThreadUtil {

fun onMainThread(runnable: Runnable) {
val mainHandler = Handler(Looper.getMainLooper())
mainHandler.post(runnable)
}
}

简化下实际上就是下面的代码。

object Singleton {

fun xxx() {
}
}

反编译后看生成代码,这就是一个典型的饿汉式单例,借助静态代码块初始化的锁,初始化单例实例,从而实现单例效果。

public final class Singleton {
public static final Singleton INSTANCE;

public final void xxx() {
}

private Singleton() {
}

static {
Singleton var0 = new Singleton();
INSTANCE = var0;
}
}

通过object代替匿名内部类

这是object的另一个比较常用的地方,也符合了object的语义,定义一个类,并生成该类的实例,也就是需要创建的匿名内部类。

viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}

override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

override fun onPageSelected(position: Int) {}
});

companion object

由于Kotlin中没有静态函数,所以在Kotlin中,可以使用companion object替代Java中的static修饰。

编译器会自动生成了一个叫做Companion的静态内部类。

在Java中调用伴生对象,可以使用User.Companion.isMale(1)

class User {

companion object {
const val DEFAULT_USER_AGE = 30
}

fun test(){}
}

// later, accessed like you would a static variable:
user.age = User.DEFAULT_USER_AGE

Kotlin函数

在Kotlin的基础库中,系统提供了大量针对函数的优化,解决了很多在Java代码中写起来不太爽的地方。

显式参数

在Java中,当一个函数的参数值太多时,需要一个个对齐参数,虽然可以通过IDE的快捷提示等功能来展示,但始终用起来不太方便,而在Kotlin中,除了像Java中那样按顺序的传递参数外,还可以通过指定参数名的方式进行参数传递。

fun test(name: String, age: Int) {
}

test(name = “xys”, age = 18)

参数含义一目了然,提高了代码的可读性。

参数默认值

fun test(name: String = “xys”, age: Int) {
}

fun a() {
test(age = 18)
}

通过参数默认值,可以避免Java下大量参数下的重载函数,当某个参数可以使用默认值时,就不用显示的声明了,类似Java中的不同参数的重载函数。

在Java、Kotlin混编的时候,无法避免的会混合调用,可以通过@JvmOverloads注解,给Java代码生成重载的函数。

拓展函数

拓展函数可以说是Kotlin最为重要的黑魔法之一了,通过拓展函数,可以给一些系统类添加原本没有的函数,极大的提高了函数的可拓展性。

fun Activity.toast(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}

拓展属性

与拓展函数类似,拓展属性可以给现有属性拓展自定义的实现。

val String.lastChar: Char
get() = get(length - 1)

拓展功能看上去比较神奇,但大家可以通过查看Kotlin生成的class代码,反编译成的Java代码来看它具体的实现方法。

对于扩展函数来说,转化为Java代码的时候,其实就是生成一个静态的函数,这个静态函数的第一个参数就是该类的实例对象,所以这样把类的实例传入函数以后,函数内部就可以访问到类的公有方法。

扩展属性也是类似,获取的扩展属性会生成为一个静态的get函数,同时这个静态函数的第一个参数就是该类的实例对象,设置的扩展属性会转化为一个静态的set函数,同时这个静态函数的第一个参数就是该类的实例对象。函数内部可以访问公有的方法和属性。

在了解了其实现原理后,可以发现,拓展函数一定是static的,且不能被override,也不存在运行时类型,其类型在编译时就已经确定,同时扩展函数和扩展属性内只能访问到类的公有方法和属性,私有的和protected同样是不能访问的。

拓展函数和拓展属性只是Kotlin语法的障眼法,并没有实际的去修改一个类

嵌套函数

函数是Kotlin中的第一公民,所以函数可以出现在Kotlin中的任何一个地方,包括在一个函数中。

在一个函数中定义另一个函数,可以很好的将这个函数的使用限制在当前的外层函数中,避免对外暴露不必要的接口,同时还能避免重复的模板代码,例如下面这个例子。

class User(val id: Int, val name: String, val address: String, val email: String)

fun check(user: User) {
if (user.name.isEmpty()) {
throw IllegalArgumentException(“Can’t save user ${user.id}: empty Name”)
}
if (user.address.isEmpty()) {
throw IllegalArgumentException(“Can’t save user ${user.id}: empty Address”)
}
if (user.email.isEmpty()) {
throw IllegalArgumentException(“Can’t save user ${user.id}: empty Email”)
}
// …

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

更多学习和讨论,欢迎加入我们的知识星球!

点击这里加入我们吧!

群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

4241218)]

[外链图片转存中…(img-qOiC0Lua-1710844241219)]

更多学习和讨论,欢迎加入我们的知识星球!

点击这里加入我们吧!

群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

这里有2000+小伙伴,让你的学习不寂寞~·

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值