ClassValue in Java 7
Its purpose it to allow adding runtime information to arbitrary target classes (reference).
I think its targeted more towards dynamic language programmers. I am not sure how it will be useful for general application developers though.
Initially the class was there in the package java.dyn
. This bug shows it moving to java.lang.
ClassValue
cache something about the class.
Here is a part of code (at 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;
}
};
The best explanation of the purpose of this class is that it solves Java Bug 6389107
There are many use cases where one wants to essentially have a Map<Class<?>, T>
for some reason, but this causes all sorts of trouble since Class
objects will then not be GC-able until the Map is. WeakHashMap<Class<?>, T>
doesn't solve the problem because very frequently, T
references the class.
The bug above goes into a much more detailed explanation and contains example projects/code that face this problem.
ClassValue is the answer to this problem. A thread-safe, classloader loading/unloading safe way to associate data with a Class.