Domanda

Sto cercando di offrire un po 'di praticità attraverso la riflessione ai programmatori che useranno il mio codice. Per ottenere il risultato desiderato, vorrei ottenere l'oggetto class per le classi che estendono il mio codice. Anche se non possono ignorare il metodo statico da cui desidero accedere alle informazioni, al momento sarebbe utile. Potrei finire semplicemente per riformattare un po 'il design per evitare questa situazione, ma volevo porre questa domanda alla comunità.

L'unico modo per ottenere ciò di cui sono a conoscenza è prendere il thread corrente, navigare nella traccia dello stack ed estrarre il nome della classe, quindi convertirlo in un'istanza effettiva della classe.

Altri suggerimenti?

Nota a margine: l'approccio sopra è anche l'unico modo in cui sono a conoscenza di ottenere il metodo di chiamata.

È stato utile?

Soluzione

Quando nel metodo statico, qual è la garanzia che una (qualsiasi) classe che è stata estesa dalla tua sia nello stack?

Se ci pensi un po ', sospetto che realizzerai che ciò che stai cercando non esiste.

/ EDIT 1 / Penso che ciò di cui hai bisogno sia

abstract class B {
    <T extends B> B create(Class<T> clazz) {
    ....
}

Hmmm. Cosa succede se create è il metodo protetto ? Quindi potresti essere abbastanza sicuro che il chiamante sia un B , puoi persino richiederlo, lanciando UnsupportedOperation o IllegalState se il chiamante non è assegnabile a B .

Puoi usare Thread.currentThread (). getStackTrace ()

Altri suggerimenti

Purtroppo non è necessariamente sicuro camminare nello stack:

Da Javadoc JDK 6 per getStackTrace:

  

Alcune macchine virtuali possono, sotto alcune   circostanze, omettere uno o più stack   fotogrammi dalla traccia dello stack. Nel   caso estremo, una macchina virtuale che   non ha informazioni sulla traccia dello stack   riguardo a questo lancio è permesso   per restituire un array di lunghezza zero da   questo metodo. In generale, il   l'array restituito con questo metodo lo farà   contiene un elemento per ogni frame   che sarebbe stampato da   printStackTrace.

Potresti, forse, usare il debugger api per farlo. Credo che il materiale di debug sia in grado di utilizzare HotSpot a tutta velocità (potrei sbagliarmi), quindi non vedresti un enorme successo per farlo. Puoi iniziare guardando: http: // java .sun.com / JavaSE / 6 / docs / note tecniche / guide / jpda / trace.html

Inoltre, basandoci sulla risposta senza risposta ...

class Base
{
    // instance method helper
    public final int foo()
    {
        return (foo(this.getClass()));
    }

    // the real helper, with access to the class
    private static int foo(final Class clazz)
    {
        return (0);
    }
}

class Child
    extends Base
{
    public void bar()
    {
        final int x;

        x = foo();
    }
}

La creazione di un lancio è molto costoso, quindi non utilizzarlo se il tuo metodo viene chiamato spesso (.e.g. più di una volta al secondo) Un approccio leggermente migliore è Thread.currentThread (). GetStackTrace ().

Un altro approccio se si utilizza la JVM di Sun è Reflection.getCallerClass (n). Questo molto più veloce ma non portabile su altre JVM. Se sei preoccupato per questo, potresti avere un altro metodo che lo chiama se è disponibile e usa la traccia dello stack in caso contrario.

Tutto questo presuppone che il tuo metodo statico NON sia pubblico. Se è tutto, le scommesse sono disattivate poiché il tuo metodo può essere chiamato da qualsiasi classe, non solo da una tua.

Suggerisco di evitare il pantano della riflessione. Sembra che tu stia facendo una sorta di programmazione semplice. Usa un'implementazione semplice (non ci sono abbastanza informazioni per indovinare cosa potrebbe essere).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top