Android面试笔记-kotlin相关

Android面试笔记-kotlin相关

1. kotlin相对于Java的优

kotlin是一种比较现代化的语言,融合了多种语言的优势。比如使用JVM的内存管理,空安全控制,lambda表达式,以及其他各种语法糖。

  • 语法简洁,减少样板代码
  • 空安全(Null Safety)
  • 扩展函数(Extension Functions)
  • 函数式编程支持,Lambda 和 高阶函数
  • 协程(Coroutines)
  • 智能类型转换(Smart Casts),is判断后屋再次强转
  • 默认参数与命名参数,减少方法重载
  • 与 Java 的完全互操作性
  • 现代语言特性,自动拆解、内联函数、密封类
  • Google官方支持与社区生态

2.高阶函数

高阶函数是可以接收函数作为参数返回函数作为结果的函数

  • 函数类型的引用
  • Lambda表达式定义匿名函数
  • 函数引用,::+函数名,传递函数引用
  • 内联函数
  • 标准库高阶函数操作符

3.内联函数

内联函数(Inline Functions) 是一种通过 inline 关键字修饰的函数,主要用于优化高阶函数(尤其是包含 Lambda 参数的函数)的性能。它的核心原理是在编译时将函数体直接插入到调用处,从而减少函数调用和 Lambda 表达式带来的额外开销。

适用场景
  • 高阶函数:当函数参数是 Lambda 时,内联可以避免创建匿名类对象(减少内存开销)。
  • 性能敏感代码:例如频繁调用的工具函数。
  • 结合 reified 类型参数:在泛型中保留类型信息
注意事项
  • 代码膨胀:内联函数会导致函数体被复制到多个调用处,如果函数体较大或调用频繁,可能增加生成的字节码大小。应避免内联大型函数。
  • 限制:内联函数不能直接访问外层类的私有成员,部分操作(如递归调用)无法内联
noinline

内联函数的某个参数是函数,则该参数默认也是 inline 的,当需要禁止这个函数参数inline,比如需要被其他非inline函数调用或者返回值,就需要使用noinline标记。

crossinline

在内联函数中的 lambda 表达式参数,可以直接使用不带标签的 return,返回的是调用内联函数的外部函数,而不是内联函数本身,默认就是非局部返回。 crossinline 标记禁止内联函数的 lambda 表达式参数使用非局部返回,即禁用return

4.扩展函数

原理:扩展函数在编译时会被转换为静态方法,接收者对象(即扩展的目标类实例)作为该静态方法的第一个参数。

  • 无法访问私有成员
  • 静态解析(非多态) :扩展函数的调用在编译时根据接收者的声明类型确定,而非运行时实际类型
kotlin 复制代码
open class Parent
class Child : Parent()

fun Parent.foo() = "Parent"
fun Child.foo() = "Child"

val obj: Parent = Child()
println(obj.foo()) // 输出 "Parent",而非 "Child"
  • 优先级低于成员方法
  • 扩展属性实现,扩展属性同样通过静态方法实现,但不会有实际字段存储,必须通过 getter(和 setter,若为 var
  • 可空接收者支持
  • 扩展函数需通过导入(import)才能使用,若存在同名冲突,需使用全限定名或别名

5.标准库中的作用域函数

Kotlin 标准库中的这些作用域函数(let, also, run, with, apply, repeat)在对象操作和代码块执行中有不同的用途和特点。它们的核心区别在于 上下文对象的引用方式返回值类型


let
  • 上下文对象 :通过 it 引用。

  • 返回值:Lambda 表达式的结果(最后一行)。

  • 使用场景

    • 处理可空对象(避免空指针)。
    • 链式调用中转换或处理对象。
  • 示例

    kotlin 复制代码
    val length = text?.let { 
        println("Processing: $it")
        it.length // 返回长度
    } ?: 0

also
  • 上下文对象 :通过 it 引用。

  • 返回值 :返回对象本身(this)。

  • 使用场景

    • 链式调用中执行副作用操作(如日志、修改对象属性)。
  • 示例

    kotlin 复制代码
    val list = mutableListOf(1, 2, 3).also {
        println("Initial list: $it")
        it.add(4) // 修改对象
    }

run
  • 上下文对象 :通过 this 引用(可省略)。

  • 返回值:Lambda 表达式的结果。

  • 变体

    • 扩展函数形式obj.run { ... }
    • 非扩展函数形式run { ... }(无上下文对象)。
  • 使用场景

    • 初始化对象并计算结果。
    • 替代 let 但需要省略 it
  • 示例

    kotlin 复制代码
    val result = Person().run {
        name = "Alice" // 直接访问属性(this 可省略)
        age = 30
        getInfo() // 返回结果
    }

with
  • 上下文对象 :通过 this 引用(参数传入)。

  • 返回值:Lambda 表达式的结果。

  • 特点:非扩展函数,直接传入对象。

  • 使用场景

    • 对对象进行多次操作,无需返回对象本身。
  • 示例

    kotlin 复制代码
    val person = Person("Bob", 25)
    val info = with(person) {
        age += 1 // 修改属性
        "Name: $name, Age: $age" // 返回结果
    }

apply
  • 上下文对象 :通过 this 引用。

  • 返回值 :返回对象本身(this)。

  • 使用场景

    • 对象初始化(如配置属性)。
  • 示例

    kotlin 复制代码
    val person = Person().apply {
        name = "Charlie"
        age = 40
        // 返回 this(Person 对象)
    }

repeat
  • 用途:重复执行代码块指定次数。

  • 返回值Unit(无返回值)。

  • 使用场景

    • 替代简单的 for 循环。
  • 示例

    kotlin 复制代码
    repeat(3) { i ->
        println("Iteration $i")
    }

对比表格

函数 上下文对象 返回值 扩展函数 典型场景
let it Lambda 结果 处理可空对象、链式转换
also it 对象本身 链式副作用操作
run this Lambda 结果 是/否 初始化对象并计算、替代 let
with this Lambda 结果 对已有对象进行多次操作
apply this 对象本身 对象初始化配置
repeat Unit 替代简单循环

选择指南

  • 需要返回对象本身 → applyalso
    • apply 配置属性(this 可省略)。
    • also 执行副作用(如日志)。
  • 需要返回计算结果 → letrunwith
    • 处理可空对象 → let
    • 需要 this 上下文 → runwith
  • 重复执行代码块指定次数 → repeat

注:主要用来面试前记一下知识点,有些是经过了Deepseek生成的

相关推荐
拉不动的猪13 分钟前
前端常见数组分析
前端·javascript·面试
tangweiguo030519871 小时前
Android Kotlin ViewModel 错误处理:最佳 Toast 提示方案详解
android·kotlin
火柴就是我2 小时前
android 基于 PhotoEditor 这个库 开发类似于dlabel的功能_2
android
每次的天空2 小时前
Android学习总结之Java篇(一)
android·java·学习
尤物程序猿3 小时前
【2025最新Java面试八股】如何在Spring启动过程中做缓存预热?
java·缓存·面试
8931519603 小时前
Android开发Glide做毛玻璃效果
android·glide·android开发·android教程·glide做毛玻璃效果
天天扭码4 小时前
JavaScript 中 apply 和 call 方法的区别与应用场景
前端·javascript·面试
whysqwhw4 小时前
DRouter代码走读
android
uhakadotcom4 小时前
持续写作的“农耕思维”:如何像农民一样播种,收获稳定成长与收入
后端·面试·github
人生游戏牛马NPC1号5 小时前
学习Android(五)玩安卓项目实战
android·kotlin