Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassValue in Java 7

Tags:

java

java-7

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.

like image 697
Jörn Horstmann Avatar asked Sep 16 '11 12:09

Jörn Horstmann


People also ask

What is ClassValue?

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.

What is the Java lang package?

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.


3 Answers

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.

like image 117
Scott Carey Avatar answered Oct 12 '22 15:10

Scott Carey


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.

like image 37
Suraj Chandran Avatar answered Oct 12 '22 15:10

Suraj Chandran


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;
    }
};
like image 45
user5630205 Avatar answered Oct 12 '22 15:10

user5630205