2011-09-16 17 views
33

Durante la navigazione la documentazione delle API Java 7 mi sono imbattuto sulla nuova classe java.lang.ClassValue con la seguente documentazione piuttosto minimale:ClassValue in Java 7

Pigramente associare un valore calcolato con (potenzialmente) ogni tipo. Ad esempio, se un linguaggio dinamico deve creare una tabella di invio messaggi per ogni classe incontrata in un messaggio invia sito di chiamata, può utilizzare uno ClassValue per memorizzare nella cache le informazioni necessarie per l'invio rapido del messaggio, per ogni classe incontrata.

Qualcuno può dare una spiegazione migliore di quale problema risolve questa classe e forse qualche codice di esempio o progetto open source che già utilizza questa classe?

Aggiornamento: Sono ancora interessato ad alcuni codice sorgente reale o esempi utilizzando questa nuova classe.

Ho trovato anche this mail on the mlvm-dev mailing list relativo ad alcuni miglioramenti dell'implementazione. Apparentemente è stato cambiato dall'utilizzo di una WeakHashMap in un nuovo campo privato su java.lang.Class per renderlo più scalabile.

+0

Leggendo l'API si è collegato al mi suggerisce che il metodo 'get()' è il il posto migliore per indizi. Non capisco perché il metodo 'get()' abbia un oggetto 'Class', comunque. – Raedwald

+0

Attualmente c'è una discussione sulla mailing list di core-libs (http://mail.openjdk.java.net/pipermail/mlvm-dev/2013-April/005321.html) riguardante l'uso di ClassValue in groovy e le sue interazioni con scarico di classe. –

risposta

9

La migliore spiegazione dello scopo di questa classe è che risolve Java Bug 6389107

ci sono molti casi di utilizzo in cui si vuole avere essenzialmente un Map<Class<?>, T> per qualche ragione, ma questo provoca ogni sorta di guai dal Class oggetti verranno quindi non essere in grado di GC fino a quando la mappa non è. WeakHashMap<Class<?>, T> non risolve il problema perché molto frequentemente, T fa riferimento alla classe.

Il bug precedente va in una spiegazione molto più dettagliata e contiene esempi di progetti/codice che affrontano questo problema.

ClassValue è la risposta a questo problema. Un modo sicuro per caricare/scaricare il classloader thread-safe per associare i dati a una classe.

6

Ha lo scopo di consentire l'aggiunta di informazioni di runtime a classi target arbitrarie (reference).

Penso che sia indirizzato più verso programmatori dinamici di linguaggio. Non sono sicuro di come sarà utile per gli sviluppatori di applicazioni generali.

Inizialmente la classe era presente nel pacchetto java.dyn. This bug mostra lo spostamento su java.lang.

1

Bene, è una classe astratta. Ho trovato uno copy. Date un'occhiata a questo.

+2

Ecco una copia di [sintassi evidenziata] (http://code.google.com/p/jsr308-langtools/source/browse/src/share/classes/java/lang/ClassValue.java?repo=basic-jdk) . –

1

ClassValue cache qualcosa sulla classe. qui è una parte di codice (a 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; 
} 
};