While browsing the Java 7 API documentation I stumbled upon the new class java.lang.ClassValue with the following rather minimal documentation:
Lazily associate a computed value with (potentially) every type. For example, if a dynamic language needs to construct a message dispatch table for each class encountered at a message send call site, it can use a
ClassValue
to cache information needed to perform the message send quickly, for each class encountered.
Can anyone give a better explanation of what problem this class solves and perhaps some sample code or open source project that already uses this class?
Update: I'm still interested in some actual source code or examples using this new class.
I also found this mail on the mlvm-dev mailing list concerning some implementation improvements. It was apparently changed from using a WeakHashMap to a new private field on java.lang.Class to make it more scalable.
Lazily associate a computed value with (potentially) every type. For example, if a dynamic language needs to construct a message dispatch table for each class encountered at a message send call site, it can use a ClassValue to cache information needed to perform the message send quickly, for each class encountered.
lang package in Java. Provides classes that are fundamental to the design of the Java programming language. The most important classes are Object, which is the root of the class hierarchy, and Class, instances of which represent classes at run time.
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.
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;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With