Domanda

E 'stato di circa 6 anni da quando ho scritto Java, quindi vi prego di scusare la ruggine.

Sto lavorando con un metodo di libreria che richiede che lo passo Class oggetti. Dal momento che dovrò richiamare questo metodo una serie dinamica di volte, ogni volta con un argomento Class leggermente diverso, ho voluto passare una classe anonima.

Tuttavia, tutta la documentazione / tutorial che ho potuto trovare finora parla solo di istanziare le classi anonime, esempio :

new className(optional argument list){classBody}

new interfaceName(){classBody}

Posso definire una classe anonima, senza un'istanza esso? O, forse più chiaramente, posso creare un oggetto Class per una classe anonima?

È stato utile?

Soluzione

Purtroppo, non c'è modo si può schivare l'istanza qui. Si può fare un no-op, invece:

foo((new Object() { ... }).getClass());

Naturalmente, questo potrebbe non essere un'opzione se si deve derivare da una classe che esegue alcune azioni nel costruttore.

Modifica

La tua domanda dice anche che si desidera chiamare foo "ogni volta con un po 'diverso argomento di classe". Quanto sopra non lo farà, perché ci sarà ancora una sola classe interna anonima definizione , anche se si mette la nuova espressione in un ciclo. Quindi non è davvero andando a comprare qualsiasi cosa rispetto a definizione di classe di nome. In particolare, se si sta cercando di fare per catturare i valori di alcune variabili locali, la nuova istanza della classe anonima che foo creerà utilizzando l'oggetto Class passato ad esso non sono loro catturati.

Altri suggerimenti

risposta breve

non si può (utilizzando solo le classi JDK)

risposta lunga

fare un tentativo:

public interface Constant {

    int value();
}

public static Class<? extends Constant> classBuilder(final int value) {
    return new Constant() {

        @Override
        public int value() {
            return value;
        }

        @Override
        public String toString() {
            return String.valueOf(value);
        }
    }.getClass();
}

diamo la creazione di due nuove classi classi "parametriche":

Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);

tuttavia non è possibile istanziare questa classe:

Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto

non riuscirà a runtime dal non v'è una sola istanza per ogni classe anonima .

Tuttavia è possibile costruire classi dinamiche in fase di esecuzione utilizzando le librerie di manipolazione bytecode come ASM . Un altro approccio sta usando proxy dinamici , ma questo approccio come lo svantaggio che si può solo procura metodi di interfaccia (quindi è necessario un'interfaccia Java).

È possibile fare riferimento solo una classe anonima UNA VOLTA. Se non si crea un'istanza di lì, non è possibile creare un'istanza da quando non si dispone di un nome per questo.

Quindi credo che le classi anonime possono essere utilizzate solo in combinazione con una "nuova BaseClass ()".

Nella tua situazione si dovrebbe passare un oggetto BaseClass per il metodo di fare il lavoro, e un'istanza dell'oggetto anonimo nel codice sorgente quando è necessario l'oggetto di passare.

Non è possibile accedere all'oggetto classe di una classe anonima, senza instatiating esso. Tuttavia, se avete solo bisogno di accedere alla classe, è possibile definire le classi locali all'interno del vostro metodo e fare riferimento a questi utilizzando la sintassi letterale ClassName.class.

È possibile assumere il nome di una classe anonima e chiamare Class.forName("mypackage.MyBaseClass$1") per ottenere un handle a una classe anonima. Questo vi darà la prima classe anonima definita nel vostro MyBaseClass, quindi questo è un modo piuttosto fragile per fare riferimento a una classe.

Ho il sospetto che ciò che si sta cercando di fare potrebbe essere fatto un modo migliore. Cosa stai veramente cercando di raggiungere? Forse siamo in grado di suggerire un modo che non richiede di passare un Class in questo modo.

È possibile accedere all'oggetto classe di una classe anonima chiamando .getClass() su di esso immediatamente dopo la creazione. Ma a cosa servirebbe?

Penso che la chiave è in questa parte di ciò che ha detto:

  

Sto lavorando con un metodo di libreria che richiede che lo passo Class   oggetti.

Perché cosa vuole di passare che gli oggetti di classe? Che cosa significa questa libreria che fare con gli oggetti di classe si passa? Le istanze degli oggetti? Ma se è così, che cosa vuol costruttore usa e come si decide quali argomenti da passare? Non so che cosa biblioteca si sta utilizzando o ciò che fa, ma direi che si crea sempre oggetti utilizzando il costruttore senza argomenti. Tuttavia, ciò non funzionerà per classi anonime comunque, poiché hanno alcun costruttore pubblico (e, in ogni caso, istanziare qualsiasi classe interna non statica, deve essere fornito un riferimento all'istanza esterno, quindi non c'è costruttore senza argomenti ).

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