2011-09-16 12 views
33

Podczas przeglądania dokumentacji Java 7 API natknąłem się nowej klasy java.lang.ClassValue z następującym raczej minimalnym dokumentacji:ClassValue w Javie 7

Lazily powiązać wartość oblicza się (potencjalnie) każdego rodzaju. Na przykład, jeśli język dynamiczny musi skonstruować tabelę wysyłania komunikatów dla każdej klasy napotkanej na stronie wysyłania wiadomości, może użyć ClassValue do przechowywania informacji o pamięci podręcznej potrzebnej do szybkiego wysłania wiadomości dla każdej napotkanej klasy.

Czy ktoś może lepiej wyjaśnić, jaki problem rozwiązuje ta klasa, a może jakiś przykładowy kod lub projekt open source, który już korzysta z tej klasy?

Aktualizacja: Nadal interesuje mnie rzeczywisty kod źródłowy lub przykłady korzystające z tej nowej klasy.

Znalazłem także this mail on the mlvm-dev mailing list dotyczące niektórych ulepszeń implementacji. Zostało najwyraźniej zmienione z używania WeakHashMap na nowe prywatne pole w java.lang.Class, aby uczynić go bardziej skalowalnym.

+0

Czytając API Ci połączoną sugeruje mi, że 'get()' metoda jest najlepszym miejscem do wskazówek. Nie rozumiem jednak, dlaczego metoda 'get()' ma obiekt 'Class'. – Raedwald

+0

Obecnie trwa dyskusja na liście dyskusyjnej core-libs (http://mail.openjdk.java.net/pipermail/mlvm-dev/2013-April/005321.html) na temat wykorzystania ClassValue w groovy i jej interakcji z klasa rozładunku. –

Odpowiedz

9

Najlepszym wyjaśnieniem celów tej klasy jest to, że rozwiązuje Java Bug 6389107

Istnieje wiele przypadków użycia, gdzie chce się zasadniczo mają Map<Class<?>, T> z jakiegoś powodu, ale to powoduje różnego rodzaju kłopoty, ponieważ Class obiekty będą następnie nie będziesz mieć zdolności GC, dopóki mapa nie będzie. WeakHashMap<Class<?>, T> nie rozwiązuje problemu, ponieważ bardzo często, T odnosi się do klasy.

Powyższy błąd zawiera dużo bardziej szczegółowe wyjaśnienie i zawiera przykładowe projekty/kod, które napotykają ten problem.

ClassValue jest odpowiedzią na ten problem. Bezpieczny sposób ładowania i rozładowywania klas ładujących klasy, umożliwiający powiązanie danych z klasą.

6

Jego celem jest umożliwienie dodawania informacji o środowisku wykonawczym do dowolnych klas docelowych (reference).

Myślę, że jest bardziej ukierunkowany na dynamicznych programistów językowych. Nie jestem pewien, w jaki sposób będzie to przydatne dla programistów aplikacji ogólnych.

Początkowo klasa była tam w opakowaniu java.dyn. This bug pokazuje, że przechodzi do java.lang.

1

Cóż, jest to klasa abstrakcyjna. Znalazłem copy. Spójrz na to.

+2

Oto kopia z [podświetloną składnią] (http://code.google.com/p/jsr308-langtools/source/browse/src/share/classes/java/lang/ClassValue.java?repo=basic-jdk) . –

1

ClassValue cache coś o klasie. tutaj jest część kodu (w 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; 
} 
};