Android面试题库
Kotlin特性
Kotlin基础

Kotlin 核心特性

本章节将介绍Kotlin语言的核心特性及其在Android开发中的最佳实践。

空安全机制

核心特性

  1. 可空类型和非空类型
  2. 安全调用操作符 ?.
  3. Elvis操作符 ?:
  4. 非空断言操作符 !!

最佳实践

// 推荐写法
fun processUser(user: User?) {
    // 使用安全调用
    val name = user?.name ?: "Unknown"
    
    // 使用作用域函数
    user?.let { 
        println("User name: ${it.name}")
    }
}

协程

核心概念

  1. 什么是协程?为什么要使用协程?
  2. 协程作用域和上下文
  3. 挂起函数的工作原理
  4. 协程调度器的类型和使用场景

实践示例

viewModelScope.launch {
    try {
        // 在IO线程执行网络请求
        val result = withContext(Dispatchers.IO) {
            api.fetchData()
        }
        // 在主线程更新UI
        updateUI(result)
    } catch (e: Exception) {
        handleError(e)
    }
}

扩展函数

使用场景

  1. 为已有类添加新功能
  2. 优化代码可读性
  3. 实现链式调用

示例

// String扩展函数
fun String.toValidEmail(): Boolean {
    return android.util.Patterns.EMAIL_ADDRESS.matcher(this).matches()
}
 
// View扩展函数
fun View.visible() {
    visibility = View.VISIBLE
}

数据类

特点

  1. 自动生成equals()/hashCode()
  2. toString()方法
  3. copy()方法
  4. 解构声明

使用示例

data class User(
    val id: Long,
    val name: String,
    val email: String
) {
    fun toUserDto() = UserDto(id, name)
}
 
// 解构声明
val user = User(1, "John", "john@example.com")
val (id, name) = user

高阶函数

核心概念

  1. 函数类型
  2. Lambda表达式
  3. 内联函数
  4. 作用域函数(let, run, with, apply, also)

实践建议

// 使用高阶函数简化代码
inline fun <T> measureTimeMillis(block: () -> T): Pair<T, Long> {
    val start = System.currentTimeMillis()
    val result = block()
    val end = System.currentTimeMillis()
    return result to (end - start)
}
 
// 使用作用域函数优化代码结构
view.apply {
    alpha = 0.5f
    visibility = View.VISIBLE
    setOnClickListener { /* 处理点击事件 */ }
}

密封类(Sealed Class)

特点

  1. 限制类继承体系
  2. 编译时类型安全
  3. when表达式无需else分支
  4. 适合表示受限的类层次结构

示例

sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    object Loading : Result<Nothing>()
}
 
fun handleResult(result: Result<String>) = when(result) {
    is Result.Success -> println("Success: ${result.data}")
    is Result.Error -> println("Error: ${result.exception.message}")
    is Result.Loading -> println("Loading...")
    // 不需要else分支
}

委托属性

核心概念

  1. 属性委托的基本原理
  2. 内置委托(lazy, observable等)
  3. 自定义委托属性
  4. 委托属性的应用场景

实践示例

class User {
    // 懒加载
    val heavyResource: String by lazy {
        // 复杂计算
        "Heavy Resource"
    }
    
    // 观察属性变化
    var name: String by Delegates.observable("initial") { 
        prop, old, new -> println("$old -> $new")
    }
    
    // 自定义委托
    var lastLoginDate: Date by PreferenceDelegate("last_login")
}
 
// 自定义属性委托
class PreferenceDelegate<T>(private val key: String) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        // 从SharedPreferences获取值
        return getPreference(key)
    }
    
    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        // 保存值到SharedPreferences
        savePreference(key, value)
    }
}

泛型和类型系统

核心特性

  1. 型变(Variance)
    • 协变(out)
    • 逆变(in)
    • 不变(invariant)
  2. 类型投影(Type Projection)
  3. 星投影(Star Projection)
  4. 泛型约束

实践示例

// 协变示例
interface Source<out T> {
    fun nextT(): T
}
 
// 逆变示例
interface Comparable<in T> {
    operator fun compareTo(other: T): Int
}
 
// 泛型约束
fun <T : Comparable<T>> sort(list: List<T>) {
    // 实现排序逻辑
}
 
// 类型投影示例
fun copy(from: Array<out Any>, to: Array<Any>) {
    // 可以安全地复制元素
}

反射机制

核心功能

  1. 类引用和类型引用
  2. 属性和函数的反射
  3. 注解的反射
  4. 运行时类型检查

使用示例

class Sample {
    var name: String = "Kotlin"
    fun process() { /* ... */ }
}
 
fun reflectionExample() {
    // 获取类引用
    val clazz = Sample::class
    
    // 获取属性
    val property = clazz.memberProperties.first { it.name == "name" }
    
    // 获取函数
    val function = clazz.memberFunctions.first { it.name == "process" }
    
    // 创建实例
    val instance = clazz.createInstance()
    
    // 调用属性和函数
    property.set(instance, "New Value")
    function.call(instance)
}

注解处理

核心概念

  1. 注解声明
  2. 注解目标
  3. 注解参数
  4. 注解处理器

实践示例

// 自定义注解
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class JsonSerializable(val name: String = "")
 
// 使用注解
@JsonSerializable("user")
data class User(val name: String)
 
// 注解处理
fun processAnnotations(clazz: KClass<*>) {
    val annotation = clazz.findAnnotation<JsonSerializable>()
    annotation?.let {
        println("Found JsonSerializable: ${it.name}")
    }
}

Kotlin与Java互操作性

核心特性

  1. @JvmStatic和@JvmField
  2. @JvmOverloads
  3. @Throws注解
  4. Java调用Kotlin
  5. Kotlin调用Java

最佳实践

class KotlinJavaInterop {
    companion object {
        @JvmStatic
        fun staticMethod() {
            // 可以作为Java静态方法调用
        }
        
        @JvmField
        val CONSTANT = "Value"
    }
    
    @JvmOverloads
    fun overloadedMethod(
        param1: String,
        param2: Int = 0,
        param3: Boolean = false
    ) {
        // Java可以调用任意参数组合
    }
    
    @Throws(IOException::class)
    fun methodWithException() {
        // Java需要捕获异常
    }
}

Java中使用Kotlin示例

// Java代码
public class JavaClass {
    public void useKotlin() {
        // 调用Kotlin伴生对象的静态方法
        KotlinJavaInterop.staticMethod();
        
        // 访问Kotlin属性
        String constant = KotlinJavaInterop.CONSTANT;
        
        // 创建Kotlin类实例
        KotlinJavaInterop interop = new KotlinJavaInterop();
        
        // 调用Kotlin方法
        interop.overloadedMethod("test");
        interop.overloadedMethod("test", 1);
        
        try {
            interop.methodWithException();
        } catch (IOException e) {
            // 处理异常
        }
    }
}