Android 高级工程师面试:泛型与反射 近1年高频追问 22 题 文章目录学习建议基础层8 题#1 为什么需要泛型Android 里解决什么问题 标准回答面试官可能继续追问#2 什么是类型擦除擦成什么 标准回答面试官可能继续追问#3 类型擦除带来哪些局限 ⭐标准回答面试官可能继续追问#4 泛型形参 T 和通配符 ? 有什么区别 ⭐标准回答面试官可能继续追问#5 List? 和 ListObject 一样吗 ⭐标准回答面试官可能继续追问#6 运行时如何获取泛型的真实类型 标准回答面试官可能继续追问#7 泛型能使用基本类型吗 ⭐标准回答面试官可能继续追问#8 反射是什么在 Android 中能做什么 ⭐标准回答面试官可能继续追问进阶层7 题#9 PECS 原则是什么怎么记 标准回答面试官可能继续追问#10 Gson 为什么需要 TypeToken 标准回答面试官可能继续追问#11 Retrofit 的 CallT 泛型是怎么工作的 标准回答面试官可能继续追问#12 获取 Class 对象有哪几种方式 ⭐标准回答面试官可能继续追问#13 Android 对反射有哪些限制 标准回答面试官可能继续追问#14 什么是隐藏 API和反射什么关系 标准回答面试官可能继续追问#15 RecyclerView.Adapter 为什么要用泛型 ⭐标准回答面试官可能继续追问核心层7 题#16 Method.invoke 的原理与注意点 标准回答面试官可能继续追问#17 R8 / ProGuard 对反射有什么影响 ⭐标准回答面试官可能继续追问#18 Kotlin reified 和 Java 泛型有什么区别 标准回答面试官可能继续追问#19 为什么不能创建泛型数组 new T[] 标准回答面试官可能继续追问#20 反射如何破坏单例 标准回答面试官可能继续追问#21 Lambda 与泛型擦除、desugar 的关系 ⭐标准回答面试官可能继续追问#22 工程上什么时候该用反射什么时候禁止 标准回答面试官可能继续追问面试策略速查必背知识高频追问加分项容易踩坑完整链路一句通相关推荐学习建议目标层级建议初级掌握基础层 8 题为何用泛型、类型擦除、T 与?区别工程联想看追问第 1 条中级通读全文进阶层能讲清 Retrofit 泛型解析、Android 反射限制、Adapter 泛型设计高级核心层加分项必答PECS、reified、R8 keep 规则能串联「擦除→Token→动态代理→混淆」链路基础层8 题#1 为什么需要泛型Android 里解决什么问题 标准回答泛型在编译期约束类型减少强转与ClassCastException让 API 自描述。编译器在调用点做类型检查擦除前已拦截大部分类型错误。面试官可能继续追问Android 里泛型解决什么问题ListUser、Retrofit CallApiResponse、LiveDataT都靠泛型表达数据形态无泛型则到处强转埋运行时崩溃风险。泛型能提升运行时性能吗主要提升类型安全与可读性运行时因擦除几乎无性能差。Kotlin 还需要关心 Java 泛型吗需要SDK 与三方库大量 Java 泛型 API互操作必考。#2 什么是类型擦除擦成什么 标准回答Java 泛型是编译期语法糖运行时泛型参数被擦除替换为边界类型或Object运行时ListString与ListInteger都是List。面试官可能继续追问Android 里理解类型擦除有什么用读 Gson、Retrofit 源码或写TypeToken都必须先理解擦除部分方法签名仍保留供反射读取。擦除后还能做instanceof ListString吗不能编译报错只能instanceof List。Kotlin 也擦除吗同样擦除除非inline reified在编译期展开具体类型。#3 类型擦除带来哪些局限 ⭐标准回答不能new T()不能创建T[]运行时难区分ListString与ListInt静态字段不能用类自身泛型参数。工程绕过工厂模式、TypeToken、ClassT入参。面试官可能继续追问Android 里擦除局限怎么绕Gson 解析ListBean、Retrofit 解析CallT都依赖 TypeToken 或父类签名还原类型。为什么要有擦除这种设计兼容 Java 5 前字节码与迁移成本历史权衡非技术最优。getClass()能区分泛型吗不能只能拿到原始List.class。#4 泛型形参T和通配符?有什么区别 ⭐标准回答T命名类型参数类/方法内可多处一致引用。?通配符表未知类型常配extends/super表上/下界。面试官可能继续追问Android 里T和?怎么用Repository 返回List? extends Item可安全只读遍历只写场景用? super T。方法泛型T和类泛型T能混用吗可以注意遮蔽阅读 Retrofit 接口时区分方法级与接口级。?能当T用吗不能随意赋值给T通配符捕获需辅助方法。#5List?和ListObject一样吗 ⭐标准回答List?未知元素类型的只读安全列表不能add除null。ListObject可添加任意对象但无法接受ListString赋值逆变不成立。面试官可能继续追问Android 里List?怎么用工具方法只遍历展示用List?实际业务更常用具体泛型或 Kotlin 集合。为什么ListString不能赋给ListObject若允许放入非 String 会破坏 String 列表类型安全。KotlinListAny对应哪个更接近可读写的顶层类型但仍与 Java 泛型逆变规则互操作时需注意。#6 运行时如何获取泛型的真实类型 标准回答局部变量泛型运行时拿不到。可行路径读父类/接口ParameterizedTypegetGenericSuperclass()可还原ApiResponseUser中的User。面试官可能继续追问Android 里怎么获取泛型真实类型GsonTypeTokenT{}匿名子类固化签名Retrofit 解析CallT同理——面试最高频泛型题之一。字段上的ListUser能反射拿到吗字段Type用getGenericType()可读ParameterizedType。ProGuard 会影响 ParameterizedType 吗若混淆改类名反射类名需 keep 规则配合。#7 泛型能使用基本类型吗 ⭐标准回答泛型T只能是引用类型基本类型需用包装类。JVM 泛型基于对象Kotlin 基本类型在泛型处仍会装箱。面试官可能继续追问Android 里基本类型泛型怎么优化SparseArray用int键避免Integer装箱是替代MapInteger, V的常用优化。自动装箱有性能问题吗热点路径频繁装箱增加分配可用Sparse*数组或原始类型集合库。KotlinInt和 Javaint在泛型里泛型处都用包装/对象表示。#8 反射是什么在 Android 中能做什么 ⭐标准回答反射是运行时检视/操作类、方法、字段的 APIClass、Method、Field。能做什么依赖注入、序列化、动态代理、测试 Mock。面试官可能继续追问Android 里反射能做什么Retrofit、Gson 内部大量使用应用层反射系统私有 API 受限应优先公开 API 或 Jetpack。反射比直接调用慢多少有开销热点路径避免框架初始化阶段可接受。Kotlin 还要学 Java 反射吗要互操作与读库源码离不开java.lang.reflect。进阶层7 题#9 PECS 原则是什么怎么记 标准回答Producer Extends只读生产者用? extends T如List? extends Fruit安全遍历。Consumer Super只写消费者用? super T如List? super Apple可addApple。面试官可能继续追问Android 里 PECS 怎么用工具方法设计集合入参时按读写方向选通配符避免无脑ListT导致调用方协变失败。Collections.copy签名体现了 PECS 吗是copy(List? super T dest, List? extends T src)是教科书例子。Kotlin 有 PECS 吗声明处型变out/in编译期处理思想对应。#10 Gson 为什么需要TypeToken 标准回答解析ListUser时擦除使运行时只剩List.classGson 不知元素类型。new TypeTokenListUser(){}把泛型写在匿名子类父类签名getType()得完整ParameterizedType。面试官可能继续追问Android 里 Gson TypeToken 典型坑网络层 JSON 解析必考错误写法会反序列化成LinkedTreeMap导致强转崩溃。不用 TypeToken 会怎样fromJson(json, List.class)得到ListMap强转崩溃或逻辑错。Moshi/Kotlinx.serialization 还要 TypeToken 吗Moshi 用Types/KotlinJsonAdapterFactoryKotlin 反射或代码生成路径不同。#11 Retrofit 的CallT泛型是怎么工作的 标准回答接口声明方法返回CallUser泛型写在方法签名。Retrofit 反射读Method的ParameterizedType得User再交Converter.Factory选 Gson/Moshi。面试官可能继续追问Android 里 RetrofitCallT怎么工作动态代理生成接口实现无手写类——解释「注解 泛型为何能自动解析 JSON」。suspend fun返回值怎么处理挂起适配器读返回类型含ResponseT包装仍依赖泛型签名。混淆后 Retrofit 失败常见原因数据模型或接口方法签名被混淆需 keep model 与接口。#12 获取Class对象有哪几种方式 ⭐标准回答三种方式类名.class对象.getClass()Class.forName(全限定名)。区别.class不触发静态初始化forName默认会触发。面试官可能继续追问Android 里获取Class怎么用Activity跳转常用Xxx.classforName注意类加载器与 ProGuard keep插件化才常碰。.class会触发静态初始化吗不会forName默认会触发。Kotlin 的User::class.java是什么等价User.classKotlin 反射还有KClass。#13 Android 对反射有哪些限制 标准回答随版本收紧非 SDK 接口灰名单/黑名单反射会抛异常或警告。隐藏ActivityThread等内部 API 不可靠Android 9 更严应使用公开 API。面试官可能继续追问Android 反射限制工程影响反射自己代码需配 R8 keep反射系统私有字段是技术债上架与兼容性风险高。如何检测用了非 SDK APIstrictmode、lint、veridex、灰名单日志。Android 16 还要背黑名单吗知道趋势「越来越严」 工程替代方案比背列表重要。#14 什么是隐藏 API和反射什么关系 标准回答hide或未公开 SDK 中的类/方法Google 用灰名单/黑名单限制反射调用。反射是调用手段隐藏 API 是调用目标——二者叠加形成「越来越严」的管控。面试官可能继续追问Android 里隐藏 API 正确做法用公开 API、AndroidX、厂商文档能力Hook 框架在新版系统极易失效。灰名单和黑名单区别限制强度不同黑名单基本不可用随版本迁移。开发插件化为什么难类加载、隐藏 API、签名与组件注册都受系统策略约束。#15RecyclerView.Adapter为什么要用泛型 ⭐标准回答AdapterVH extends ViewHolder让onCreate/onBind返回/接收具体VH避免强转。常配合ListItem或DiffUtil.ItemCallbackItem保持一致。面试官可能继续追问Android 里 Adapter 泛型怎么用多类型列表用 sealed class 多 ViewHolder是业务代码里最常见的泛型场景之一。多 ViewType 怎么保持类型安全sealed/when分支绑定不同 VH或泛型委托给多个 adapter。ComposeLazyColumn还要 Adapter 泛型吗UI 层换 Compose但 diff/列表数据模型泛型思想相同。核心层7 题#16Method.invoke的原理与注意点 标准回答invoke通过Method对象调用目标实例方法传对象静态方法传null。内部做访问检查与装箱setAccessible(true)可破坏封装。面试官可能继续追问Android 里Method.invoke注意什么Retrofit 动态代理、测试框架会用到Android 9 对非公开成员更严格热点路径避免反射。invoke 能传基本类型吗用包装类或MethodType注意重载匹配。反射调用能被内联优化吗难热点路径避免反射。#17 R8 / ProGuard 对反射有什么影响 ⭐标准回答混淆改名/删除「看似未使用」的类与方法导致Class.forName、getDeclaredField失败。keep 范围Gson 模型、Retrofit 接口、序列化字段、JNI 类。面试官可能继续追问Android 里 R8 对反射怎么配AGP 默认 R8面试结合项目说「模型 keep、反射入口 keep、release 包跑核心链路验证」。Gson 要 keep 哪些数据类字段名、无参构造、泛型签名相关类。怎么验证混淆正确release 包跑核心链路 反射/JSON 单测。#18 Kotlinreified和 Java 泛型有什么区别 标准回答Java 泛型擦除运行时无法用T::class拿具体类型。Kotlininlinereified T编译期嵌入具体类型运行时可用T::class。面试官可能继续追问Android 里reified怎么用inline fun reified T gson()可简化 TypeToken跨模块非 inline 边界仍擦除。reified 能用在类里吗不能只能 inline 函数或伴生对象 inline。和 TypeToken 比哪个好Kotlin 项目优先 reified 简化Java 库仍靠 TypeToken。#19 为什么不能创建泛型数组new T[] 标准回答数组运行时保留元素类型且协变String[]可当Object[]写入Object与擦除后的泛型不一致。若允许new T[]会破坏类型安全堆污染。面试官可能继续追问Android 里泛型数组替代方案改用ArrayListTtoArray(T[])需传入具体类数组实例。ListString[]为什么也不建议堆污染heap pollution编译警告运行可能ArrayStoreException。KotlinArrayT呢运行时仍是对象数组元素类型检查在 JVM 层。#20 反射如何破坏单例 标准回答单例靠私有构造反射setAccessible(true)newInstance可造第二个实例。防御枚举单例构造器内防二次创建抛异常。面试官可能继续追问Android 面试里反射破单例考什么考反射权力边界与枚举单例优势SDK 单例不要求你破坏。序列化也能破坏单例吗能需readResolve枚举单例免疫。依赖注入还要单例吗用 Hilt 作用域管理少手写 DCL。#21 Lambda 与泛型擦除、desugar 的关系 ⭐标准回答Java 8 lambda 在 Android 经 desugar 转匿名类或invokedynamic非 JVM 原生 Java 8。捕获的泛型变量仍受擦除限制ComparatorUser的比较逻辑在User类型上下文。面试官可能继续追问Android 里 Lambda 与擦除关系读字节码或排查低版本 API 时需知 AGP 脱糖Stream 部分 API 可用但 UI 热路径慎用。Stream 在 Android 能用吗部分 API 需 desugar且注意性能与 API 级别。Kotlin lambda 和 Java lambda 互操作SAM 转换Function0等接口注意 null 与 inline。#22 工程上什么时候该用反射什么时候禁止 标准回答该用框架层序列化、DI、动态代理、测试、读自身模块且已 keep 的类。禁止/慎用调系统隐藏 API、替代简单工厂、热点路径、无 keep 的 release 反射。面试官可能继续追问Android 工程上反射怎么取舍现代栈优先注解处理器Room、Moshi codegen、Hilt、公开 API反射是备胎非默认架构。注解处理器和反射优劣编译期生成代码无运行时开销、无混淆坑首选。插件化为什么依赖反射动态加载 Dex 需ClassLoader加载未知类复杂度高。面试策略速查面试等级建议掌握初级★★★☆☆中级★★★★☆高级★★★★★必背知识类型擦除、获取泛型真实类型、TypeToken、RetrofitCallT、Android 反射限制、隐藏 API、reified 对比、工程反射取舍高频追问「擦除后怎么解析 List」「Gson 为何用 TypeToken」「反射为何被限制」「R8 怎么 keep」加分项PECS、invoke 原理、泛型数组禁令、反射破单例、Lambda desugar容易踩坑以为运行时能instanceof ListStringfromJson不传 TypeTokenrelease 未 keep 模型调灰名单 API滥用反射替代简单工厂完整链路一句通泛型反射一条线编译期泛型保类型安全擦除后靠父类签名/TypeToken/reified 找回真实类型Retrofit 与 Gson 据此解析 JSON反射能读写字节码元数据但受隐藏 API 与 R8 约束工程上注解处理 公开 API 优先反射只作框架与备胎。相关推荐Android 高级工程师面试Java 基础知识 近1年高频追问 22 题Android 高级工程师面试Java 多线程与并发 近1年高频追问 22 题