尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Android 高级工程师面试:泛型与反射 近1年高频追问 22 题

Android 高级工程师面试:泛型与反射 近1年高频追问 22 题
📅 发布时间:2026/7/6 14:21:14

文章目录

  • 学习建议
  • 基础层(8 题)
    • #1 为什么需要泛型?Android 里解决什么问题? 🔥
      • 标准回答
      • 面试官可能继续追问
    • #2 什么是类型擦除?擦成什么? 🔥
      • 标准回答
      • 面试官可能继续追问
    • #3 类型擦除带来哪些局限? ⭐
      • 标准回答
      • 面试官可能继续追问
    • #4 泛型形参 `T` 和通配符 `?` 有什么区别? ⭐
      • 标准回答
      • 面试官可能继续追问
    • #5 `List<?>` 和 `List<Object>` 一样吗? ⭐
      • 标准回答
      • 面试官可能继续追问
    • #6 运行时如何获取泛型的真实类型? 🔥
      • 标准回答
      • 面试官可能继续追问
    • #7 泛型能使用基本类型吗? ⭐
      • 标准回答
      • 面试官可能继续追问
    • #8 反射是什么?在 Android 中能做什么? ⭐
      • 标准回答
      • 面试官可能继续追问
  • 进阶层(7 题)
    • #9 PECS 原则是什么?怎么记? 💡
      • 标准回答
      • 面试官可能继续追问
    • #10 Gson 为什么需要 `TypeToken`? 🔥
      • 标准回答
      • 面试官可能继续追问
    • #11 Retrofit 的 `Call<T>` 泛型是怎么工作的? 🔥
      • 标准回答
      • 面试官可能继续追问
    • #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 里泛型解决什么问题?
    List<User>、Retrofit Call<ApiResponse>、LiveData<T>都靠泛型表达数据形态;无泛型则到处强转,埋运行时崩溃风险。

  • 泛型能提升运行时性能吗?
    主要提升类型安全与可读性,运行时因擦除几乎无性能差。

  • Kotlin 还需要关心 Java 泛型吗?
    需要,SDK 与三方库大量 Java 泛型 API,互操作必考。


#2 什么是类型擦除?擦成什么? 🔥

标准回答

Java 泛型是编译期语法糖,运行时泛型参数被擦除,替换为边界类型或Object;运行时List<String>与List<Integer>都是List。

面试官可能继续追问

  • Android 里理解类型擦除有什么用?
    读 Gson、Retrofit 源码或写TypeToken都必须先理解擦除;部分方法签名仍保留供反射读取。

  • 擦除后还能做instanceof List<String>吗?
    不能,编译报错;只能instanceof List。

  • Kotlin 也擦除吗?
    同样擦除,除非inline reified在编译期展开具体类型。


#3 类型擦除带来哪些局限? ⭐

标准回答

不能new T();不能创建T[];运行时难区分List<String>与List<Int>;静态字段不能用类自身泛型参数。工程绕过:工厂模式、TypeToken、Class<T>入参。

面试官可能继续追问

  • Android 里擦除局限怎么绕?
    Gson 解析List<Bean>、Retrofit 解析Call<T>都依赖 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<?>和List<Object>一样吗? ⭐

标准回答

List<?>:未知元素类型的只读安全列表,不能add(除null)。List<Object>:可添加任意对象,但无法接受List<String>赋值(逆变不成立)。

面试官可能继续追问

  • Android 里List<?>怎么用?
    工具方法只遍历展示用List<?>;实际业务更常用具体泛型或 Kotlin 集合。

  • 为什么List<String>不能赋给List<Object>?
    若允许,放入非 String 会破坏 String 列表类型安全。

  • KotlinList<Any>对应哪个?
    更接近可读写的顶层类型,但仍与 Java 泛型逆变规则互操作时需注意。


#6 运行时如何获取泛型的真实类型? 🔥

标准回答

局部变量泛型运行时拿不到。可行路径:读父类/接口ParameterizedType;getGenericSuperclass()可还原ApiResponse<User>中的User。

面试官可能继续追问

  • Android 里怎么获取泛型真实类型?
    GsonTypeToken<T>{}匿名子类固化签名;Retrofit 解析Call<T>同理——面试最高频泛型题之一。

  • 字段上的List<User>能反射拿到吗?
    字段Type用getGenericType()可读ParameterizedType。

  • ProGuard 会影响 ParameterizedType 吗?
    若混淆改类名,反射类名需 keep 规则配合。


#7 泛型能使用基本类型吗? ⭐

标准回答

泛型T只能是引用类型,基本类型需用包装类。JVM 泛型基于对象;Kotlin 基本类型在泛型处仍会装箱。

面试官可能继续追问

  • Android 里基本类型泛型怎么优化?
    SparseArray用int键避免Integer装箱,是替代Map<Integer, V>的常用优化。

  • 自动装箱有性能问题吗?
    热点路径频繁装箱增加分配,可用Sparse*数组或原始类型集合库。

  • KotlinInt和 Javaint在泛型里?
    泛型处都用包装/对象表示。


#8 反射是什么?在 Android 中能做什么? ⭐

标准回答

反射是运行时检视/操作类、方法、字段的 API(Class、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 怎么用?
    工具方法设计集合入参时按读写方向选通配符,避免无脑List<T>导致调用方协变失败。

  • Collections.copy签名体现了 PECS 吗?
    是,copy(List<? super T> dest, List<? extends T> src)是教科书例子。

  • Kotlin 有 PECS 吗?
    声明处型变(out/in)编译期处理,思想对应。


#10 Gson 为什么需要TypeToken? 🔥

标准回答

解析List<User>时擦除使运行时只剩List.class,Gson 不知元素类型。new TypeToken<List<User>>(){}把泛型写在匿名子类父类签名,getType()得完整ParameterizedType。

面试官可能继续追问

  • Android 里 Gson TypeToken 典型坑?
    网络层 JSON 解析必考;错误写法会反序列化成LinkedTreeMap导致强转崩溃。

  • 不用 TypeToken 会怎样?
    fromJson(json, List.class)得到List<Map>,强转崩溃或逻辑错。

  • Moshi/Kotlinx.serialization 还要 TypeToken 吗?
    Moshi 用Types/KotlinJsonAdapterFactory;Kotlin 反射或代码生成路径不同。


#11 Retrofit 的Call<T>泛型是怎么工作的? 🔥

标准回答

接口声明方法返回Call<User>,泛型写在方法签名。Retrofit 反射读Method的ParameterizedType得User,再交Converter.Factory选 Gson/Moshi。

面试官可能继续追问

  • Android 里 RetrofitCall<T>怎么工作?
    动态代理生成接口实现,无手写类——解释「注解 + 泛型为何能自动解析 JSON」。

  • suspend fun返回值怎么处理?
    挂起适配器读返回类型(含Response<T>包装),仍依赖泛型签名。

  • 混淆后 Retrofit 失败常见原因?
    数据模型或接口方法签名被混淆,需 keep model 与接口。


#12 获取Class对象有哪几种方式? ⭐

标准回答

三种方式:类名.class;对象.getClass();Class.forName("全限定名")。区别:.class不触发静态初始化;forName默认会触发。

面试官可能继续追问

  • Android 里获取Class怎么用?
    Activity跳转常用Xxx.class;forName注意类加载器与 ProGuard keep,插件化才常碰。

  • .class会触发静态初始化吗?
    不会;forName默认会触发。

  • Kotlin 的User::class.java是什么?
    等价User.class,Kotlin 反射还有KClass。


#13 Android 对反射有哪些限制? 🔥

标准回答

随版本收紧,非 SDK 接口(灰名单/黑名单)反射会抛异常或警告。隐藏ActivityThread等内部 API 不可靠;Android 9+ 更严,应使用公开 API。

面试官可能继续追问

  • Android 反射限制工程影响?
    反射自己代码需配 R8 keep;反射系统私有字段是技术债,上架与兼容性风险高。

  • 如何检测用了非 SDK API?
    strictmode、lint、veridex、灰名单日志。

  • Android 16 还要背黑名单吗?
    知道趋势「越来越严」+ 工程替代方案比背列表重要。


#14 什么是隐藏 API?和反射什么关系? 🔥

标准回答

@hide或未公开 SDK 中的类/方法,Google 用灰名单/黑名单限制反射调用。反射是调用手段;隐藏 API 是调用目标——二者叠加形成「越来越严」的管控。

面试官可能继续追问

  • Android 里隐藏 API 正确做法?
    用公开 API、AndroidX、厂商文档能力;Hook 框架在新版系统极易失效。

  • 灰名单和黑名单区别?
    限制强度不同,黑名单基本不可用,随版本迁移。

  • 开发插件化为什么难?
    类加载、隐藏 API、签名与组件注册都受系统策略约束。


#15RecyclerView.Adapter为什么要用泛型? ⭐

标准回答

Adapter<VH extends ViewHolder>让onCreate/onBind返回/接收具体VH,避免强转。常配合List<Item>或DiffUtil.ItemCallback<Item>保持一致。

面试官可能继续追问

  • 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拿具体类型。Kotlininline+reified 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 里泛型数组替代方案?
    改用ArrayList<T>;toArray(T[])需传入具体类数组实例。

  • List<String>[]为什么也不建议?
    堆污染(heap pollution),编译警告,运行可能ArrayStoreException。

  • KotlinArray<T>呢?
    运行时仍是对象数组,元素类型检查在 JVM 层。


#20 反射如何破坏单例? 💡

标准回答

单例靠私有构造,反射setAccessible(true)+newInstance可造第二个实例。防御:枚举单例;构造器内防二次创建抛异常。

面试官可能继续追问

  • Android 面试里反射破单例考什么?
    考反射权力边界与枚举单例优势;SDK 单例不要求你破坏。

  • 序列化也能破坏单例吗?
    能,需readResolve;枚举单例免疫。

  • 依赖注入还要单例吗?
    用 Hilt 作用域管理,少手写 DCL。


#21 Lambda 与泛型擦除、desugar 的关系? ⭐

标准回答

Java 8 lambda 在 Android 经 desugar 转匿名类或invokedynamic,非 JVM 原生 Java 8。捕获的泛型变量仍受擦除限制;Comparator<User>的比较逻辑在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、RetrofitCall<T>、Android 反射限制、隐藏 API、reified 对比、工程反射取舍

高频追问

「擦除后怎么解析 List」「Gson 为何用 TypeToken」「反射为何被限制」「R8 怎么 keep」

加分项(💡)

PECS、invoke 原理、泛型数组禁令、反射破单例、Lambda desugar

容易踩坑

以为运行时能instanceof List<String>;fromJson不传 TypeToken;release 未 keep 模型;调灰名单 API;滥用反射替代简单工厂


完整链路一句通

泛型反射一条线:编译期泛型保类型安全,擦除后靠父类签名/TypeToken/reified 找回真实类型,Retrofit 与 Gson 据此解析 JSON;反射能读写字节码元数据但受隐藏 API 与 R8 约束,工程上注解处理 + 公开 API 优先,反射只作框架与备胎。


相关推荐

Android 高级工程师面试:Java 基础知识 近1年高频追问 22 题

Android 高级工程师面试:Java 多线程与并发 近1年高频追问 22 题

相关新闻

  • PyTorch/TensorFlow 训练日志解析:5 行代码自动绘制 Loss/Acc 曲线(告别手动保存 .txt)
  • # 计算机知识与技术大纲详解报告(五)——信息资源管理、新进展、专业英语与软件设计
  • 泊松分布实战指南:从事件计数到业务决策

最新新闻

  • Apollo Save Tool:PS4游戏存档管理的本地化技术解决方案
  • 从FNN到LSTM:4类神经网络结构演进与10个关键设计思想解析
  • 5分钟掌握camera-controls:打造流畅3D相机控制的终极指南 [特殊字符]
  • 如何通过 docui 高效管理 Docker 网络与存储卷:终极指南
  • 3个步骤告别BT下载慢:trackerslist项目让你的下载速度提升300%
  • Hermes Agent:构建下一代智能代理框架的模块化架构与实践指南

日新闻

  • AI智能体安全防护框架AgentGuard:从原理到实战部署指南
  • KMX63与PIC18F26K40硬件组合及低功耗设计实践
  • 基于YOLO13改进的门体检测模型:C3k2模块与PoolingFormer技术解析

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号