0

我最近正在研究一些 Android 代码(这应该是一个通用的 Java 问题——请原谅双关语——关于泛型和 Java 自动解析类型)。

这是我的代码(基于 Android,但如果需要,请创建 Java 特定版本)

class ViewFinder<T extends View> {

    @SuppressWarnings("unchecked")
    final static <T> T byId(View view, int resource) {

        return (T) view.findViewById(resource);


    }

}

这是有趣的一点……

// Convert XML UI component definitions into the static View Holder object

// Here is what we normally have to do for Android to convert the XML into a UI component
holder.txtGroupName = (TextView) row.findViewById(R.id.txtGroupName);

// This is what I can do with my ViewFinder class above!        
holder.txtGroupName = ViewFinder.byId(row, R.id.txtGroupName);

// This is what I was EXPECTING to do with my ViewFinder class above!       
holder.txtGroupName = ViewFinder<TextView>.byId(row, R.id.txtGroupName);

不,我知道 Java(不是 Android)正在将 Generic T 类型解析为 TextView UI 组件,但为什么和 *如何*

我可以了解这里发生的事情吗?我希望能够在下次编写代码之前弄清楚这是否会发生。

4

1 回答 1

1

我的猜测是您正在运行 Java 7,请查看:http ://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

了解正在发生的事情的表面:Java 编译器的部分任务是

  • Parsing - 粗略的语法检查并构建抽象语法树 AST。
  • 除草 - 进一步检查 AST。
  • TypeValidation - 我认为这就是奇迹发生的地方,此时验证 AST 并在每个节点上为变量、表达式等添加标记。TypeValidation 过程将类型添加到节点并确保这些是正确的。随着 Java 7 类型的推断,我假设这个阶段被扩展为在赋值的右侧自动添加类型,如果当然有效的话。当进行下一阶段的事情时,例如 List<String> str = new ArrayList<>(),被翻译为List<String> str = new ArrayList<String>()
  • ...
  • 最后输出Java字节码,作为bonusinfo总是以0xCAFEBABE开头。

希望这是有道理的

于 2013-09-26T07:03:37.193 回答