Android 面试题咨询 “编译中生成的类,怎么让外部调用(不能先编译)”

2021 年 1 月 17 日
 zpxshl

如题。 某大厂的面试题, 求大佬指点下思路或者给个关键字。

15308 次点击
所在节点    Android
20 条回复
skyinu
2021 年 1 月 17 日
写一个中间类提供给外部调用?中间类自己反射调用生成类?
woodnaonly
2021 年 1 月 17 日
依赖 jar 不编译
xcstream
2021 年 1 月 17 日
private class
jon97
2021 年 1 月 17 日
原谅我题目都看不太懂😭
loshine1992
2021 年 1 月 17 日
这个问的是 ButterKnife 等使用 APT 的库的原理
zpxshl
2021 年 1 月 17 日
@loshine1992 大佬,能稍微展开讲讲吗? 我看了 ButterKnife 的原理,生成 r2 和代码,r2 只是为了让编译通过(注解不能使用变量,因此不能用 R )。 生成的代码里面还是使用了 R.id.xxxx 。 可这和题目有啥关系...
nnqijiu
2021 年 1 月 17 日
编译中生成的类是啥意思?
zpxshl
2021 年 1 月 17 日
@nnqijiu 有些类是编译阶段才生成的。 比如 R.java
liuzhedash
2021 年 1 月 17 日
问就是反射
fox0001
2021 年 1 月 17 日
编译生成的类,继承已生成的父类或者接口,可以不?除了把数据编译进方法中,没想到有什么好处…
twoyuan
2021 年 1 月 17 日
应该是 #1 、#5 说的类似 ButterKnife 实现的这种方式,根据注解生成了类,实际对生成的类调用时使用反射。

很久不用这个库了,可以顺着 ButterKnife.bind 入口往里翻就能找到答案(如果它没改实现方案的话)
Guaidaodl
2021 年 1 月 17 日
通常来说这种问题有两个方向. 一个是注解(Annotation), 另外一个是 Ttransform.

1. 注解的处理流程是在编译之前的. 所以其实你就直接引用你要生成的类就好. 因为注解在编译前处理, 所以编译是可以正常通过的. 如果不想在 build 之前 Android Studio 显示错误的话, 通常偷取一个接口和一个工厂类 /方法, 里面会用放射的方式来创建实现类.

2. Transform 流程可以直接修改字节码, 是在编译成 class 文件后进行的. 这里通常就是反射加工厂了.

还有一种可能是 SPI. 不过 SPI 的实现通常都是手写的实现的. 很少是编译期间生成的.
zpxshl
2021 年 1 月 18 日
@twoyuan 感谢,明早我看下 bufferknife 的源码,之前对它的分析停留在几篇文章上......
lxilu
2021 年 1 月 18 日
什么叫不能先编译?
kingfalse
2021 年 1 月 18 日
运行时动态编译?
Cabana
2021 年 1 月 18 日
1,接口
2,反射
wjploop
2021 年 1 月 18 日
编译前和编译后处理的对象分别是*.java 和*.class,这里要求编译前,可以使用解析 java 文件的库[javaparser]( https://javaparser.org/),类似 Jsoup 于*.xml
unco020511
2021 年 1 月 18 日
对不起,我连题目都没看明白
Anarchy
2021 年 1 月 18 日
编译中生成的只是 ide 不提示你知道也可以写代码正常走编译流程。如果是动态加载的就搞个中间类反射调用。
zpxshl
2021 年 1 月 23 日
@twoyuan ButterKnife.bind 顺着这入口,很快就找到答案了,感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/745660

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX