2013-10-01 6 views
5

Esiste una tecnica standard per "estendere" una classe con costruttori privati, come con la maggior parte delle classi Singleton? In particolare, sto cercando di estendere la classe java.lang.management.ThreadInfo perché sto aggiungendo un sacco di loro a un HashSet per controllare l'unicità. Tuttavia, il modo in cui determino se due thread sono uguali è diverso e non identico all'implementazione predefinita del metodo equals().Tecnica per estendere una classe con costruttori privati ​​

L'estensione della classe non è ovviamente un'opzione in questo caso.

sarebbe ragionevole fare qualcosa di simile a una classe wrapper che accetta un ThreadInfo nel costruttore e poi popola manualmente tutti i campi pertinenti con il valore e poi prevale equals() e hashCode(), o c'è un modo migliore per fare questo?

Qualcosa di simile è quello che sto iniziando a scrivere, ma un'implementazione migliore sarebbe l'ideale:

class ThreadInfoWrapper { 

    private ThreadInfo info; 
    ThreadInfoWrapper(ThreadInfo info) { 
     this.info = info; 
    } 

    //Populate instance variables with Thread.State, thread ID, etc.. with 
    //Getters/setters and all that other stuff 

    public boolean equals(Object o) { //Unique implementation 
    } 

    public int hashCode() { //Whatever implementation 
    } 

} 

Ma questo si sente come un modo molto indiretto per ottenere alcune funzionalità di base. Ho esaminato il problema e le implementazioni di set con comparatori personalizzati non esistono nella libreria standard Java. Suppongo che potrei scrivere la mia implementazione di hash set ma è troppo lavoro per una situazione semplice. Qualsiasi intuizione sarebbe utile.

+0

Sono abbastanza sicuro che tali corsi non possano essere estesi. –

+0

@JakobWeisblat In realtà, possono essere estesi, ma solo dalle loro classi interne che non sono utili in questa situazione. Capisco che estenderli nel mio file di classe non funzionerà. Sto cercando alternative ragionevoli e in particolare per vedere se ci sono pratiche standard. Non ho trovato nessuno dopo aver cercato un po '. – Kon

+0

buona fortuna allora. –

risposta

2

Con estensione, si intende come creare classi derivate, che fanno uso del costruttore privato come costruttore super-classe. Non puoi, sono stati resi privati ​​per impedirti di farlo. Poiché le classi JRE sono state scritte da programmatori competenti, ci saranno buone ragioni per questo. Quindi, anche se potresti aggirare il problema usando l'inganno, come la riflessione o la manipolazione del codice, non dovresti farlo.

Ma non tutto è perduto. Dovresti comunque preferire la composizione all'eredità. I pattern di progettazione Decorator e Proxy possono essere utili (il tuo esempio è vicino a questi).

1

Penso che quello che stai facendo è ragionevole dato che ci sono poche altre opzioni.

Un'alternativa potrebbe essere quella di scrivere la propria sottoclasse di HashMap che utilizza il proprio "speciale" uguale al valore predefinito. (Ci possono essere già implementazioni Apache o guava per fare questo -? Qualcuno sa estemporaneo)

(aggiunto in seguito)

Siccome sono pigro, e perché ThreadInfo ha tutti i getter quindi è abbastanza "sicuro" per esporre , sarei tentato di fare la classe wrapper molto semplice, senza getter né setter:

public class ThreadInfoWrapper { 

// public so an outsider can get at the wrapped ThreadInfo 
// could be private if you are sure that will never be necessary 
public final ThreadInfo threadInfo; 

public ThreadInfoWrapper(ThreadInfo threadInfo) { 
    this.threadInfo = threadInfo; 
} 

public boolean equals(Object o) { //Unique implementation 
    // refer to threadInfo.blah... 
} 

public int hashCode() { //Whatever implementation 
    // refer to threadInfo.blah... 
} 

}

Tuttavia, questo dipende proprio quello informazioni che si sta utilizzando per i vostri pari e codice hash.

+0

Grazie per la risposta. Durante la ricerca, ho trovato questa risposta (http://stackoverflow.com/questions/14880450/java-hashset-with-a-custom-equality-criteria) affermando che Guava aveva "rifiutato in modo specifico" l'implementazione di un set con criteri di uguaglianza incompatibili con il metodo 'equals()'. – Kon

+0

Sembra che tu abbia fatto la tua ricerca. In bocca al lupo. – user949300