在浏览Java 7 API文档时,我偶然发现了新的类java.lang.ClassValue,其中包含以下相当少的文档:
懒洋洋地将计算值与(可能)每种类型相关联。例如,如果动态语言需要为消息发送调用站点遇到的每个类构造消息调度表,则可以使用
ClassValue
来缓存为遇到的每个类快速执行消息发送所需的信息。
任何人都可以更好地解释这个类解决的问题,以及可能已经使用过这个类的一些示例代码或开源项目吗?
更新:我仍然对使用这个新类的一些实际源代码或示例感兴趣。
我还发现this mail on the mlvm-dev mailing list涉及一些实施改进。显然,从使用WeakHashMap变为java.lang.Class上的新私有字段,使其更具可扩展性。
答案 0 :(得分:11)
本课程目的的最佳解释是它解决了Java Bug 6389107
有许多用例由于某种原因人们想要基本上拥有Map<Class<?>, T>
,但这会导致各种麻烦,因为Class
对象在Map之前不会是GC。 WeakHashMap<Class<?>, T>
无法解决问题,因为T
经常引用该类。
上面的错误进入更详细的解释,并包含面临此问题的示例项目/代码。
ClassValue就是这个问题的答案。一种线程安全的类加载器加载/卸载安全的方法,用于将数据与类关联。
答案 1 :(得分:6)
它的目的是允许将运行时信息添加到任意目标类(reference)。
我认为它更多地针对动态语言程序员。我不确定它对普通应用程序开发人员有什么用处。
最初,课程在java.dyn
包中。 This bug显示它正在转向java.lang。
答案 2 :(得分:1)
嗯,这是一个抽象类。我找到了copy。看看吧。
答案 3 :(得分:1)
ClassValue缓存关于类的一些东西。 这是代码的一部分(在lucene 5.0 AttributeSource.java)
/** a cache that stores all interfaces for known implementation classes for performance (slow reflection) */
private static final ClassValue<Class<? extends Attribute>[]> implInterfaces = new ClassValue<Class<? extends Attribute>[]>() {
@Override
protected Class<? extends Attribute>[] computeValue(Class<?> clazz) {
final Set<Class<? extends Attribute>> intfSet = new LinkedHashSet<>();
// find all interfaces that this attribute instance implements
// and that extend the Attribute interface
do {
for (Class<?> curInterface : clazz.getInterfaces()) {
if (curInterface != Attribute.class && Attribute.class.isAssignableFrom(curInterface)) {
intfSet.add(curInterface.asSubclass(Attribute.class));
}
}
clazz = clazz.getSuperclass();
} while (clazz != null);
@SuppressWarnings({"unchecked", "rawtypes"}) final Class<? extends Attribute>[] a =
intfSet.toArray(new Class[intfSet.size()]);
return a;
}
};