问题
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.
回答1:
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.
回答2:
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.
回答3:
Well, it is an abstract class. I've found a copy. Have a look at it.
回答4:
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;
}
};
来源:https://stackoverflow.com/questions/7444420/classvalue-in-java-7