为何javac源码中closure(Type)对非类/接口类型返回非空列表?
关于javac中
closure(Type)方法文档与行为不符的疑问 在javac源码中,存在一个接收com.sun.tools.javac.code.Type类型参数、返回类型闭包的方法closure(Type),其文档明确标注仅适用于「类或接口类型」,但实际该方法对诸多其他类型也可执行,返回仅包含自身的单元素列表,明显违背了自身的文档说明:
/** * Returns the closure of a class or interface type. */ public List<Type> closure(Type t) { List<Type> cl = closureCache.get(t); if (cl == null) { Type st = supertype(t); if (!t.isCompound()) { // <line 5> if (st.hasTag(CLASS)) { cl = insert(closure(st), t); } else if (st.hasTag(TYPEVAR)) { cl = closure(st).prepend(t); } else { cl = List.of(t); } } else { cl = closure(supertype(t)); } for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) cl = union(cl, closure(l.head)); closureCache.put(t, cl); } return cl; }
对不熟悉javac源码的补充说明:
- 此处的
List并非java.util.List,是javac内部实现的链表结构 Type也不是java.lang.reflect.Type,是javac自己的类型抽象- 代码中的「compound」
Type本质对应Java语言模型中的IntersectionType(交叉类型)
从代码第5行的逻辑来看:若类型非复合类型(比如数组、基本类型、可执行类型等),且其父类型既不是类也不是类型变量时,会直接返回仅包含该类型自身的单元素列表。这就导致传入非类、接口或交叉类型时,方法都会返回这样的结果。
举个具体的例子:java.lang.Integer[]类型显然存在父类型java.lang.Number[],这和部分无父类型的基本类型不同。但按照方法文档的描述,传入数组类型应该返回空列表(因为文档说明闭包是类或接口类型的所有父类型和接口的列表),可实际返回的却是仅包含传入数组类型自身的单元素列表。
这是为什么?(注:清楚这是有着数十年历史的老代码,可能最终答案就是“无人知晓”)
内容的提问来源于stack exchange,提问作者Laird Nelson
相关产品推荐
相关产品推荐

