2009-11-05 18 views
6

Esiste un modo per sostituire (eseguire l'override) un'implementazione della classe Java, che è già caricata dal caricatore della classe System da un'altra implementazione (disponibile come array di byte)?Implementazione della classe sostitutiva (override) in Runtime (Java)

Per illustrare il mio dubbio, segue questo codice:

public class Main { 
    public static void main(String ... args) { 
     Foo foo = new Foo(); 
     foo.print(); 

     ClassLoader cl = ... 

     Foo foo2 = (Foo) cl.newInstance(); 
     foo2.print(); 
    } 
} 

Il metodo print() delle prime stampe Foo "Attuazione 1", come la seconda stampe "Attuazione 2". La seconda istanza di foo viene recuperata dal programma di caricamento classi da una matrice di byte (che può essere archiviata in un file o ottenuta da qualsiasi stream ...)

PS: è un requisito che Foo è una classe, non un'interfaccia e non può essere estesa, ovvero i byte effettivi (all'interno della VM) che definiscono l'implementazione della classe sono sovrascritti.

+0

sei positivo che vuoi davvero farlo? sarebbe bene spiegare perché nella domanda. –

risposta

0

CGLib fa cose come questa. Viene utilizzato in primavera & Hibernate per questo scopo.

0

È possibile implementare un agente di strumentazione e utilizzare java.lang.instrument.Instrumentation # redefineClasses (...) per sostituire il bytecode delle classi già caricate.

4

Sì, questo non è un problema. Dovresti usare un java.net.URLClassLoader. Ad esempio, potresti dargli un URL che è una directory in cui risiede il tuo file Foo.class preprogrammato.

Modifica: Quindi la chiamata desiderata è cl.loadClass("Foo").newInstance(). Non è possibile trasmettere il risultato a Foo, ma è possibile utilizzare la riflessione per chiamare il suo metodo print. Oppure fai di Foo una sottoclasse (o implementazione di interfaccia) di qualcosa che non si sta reimplementando, che definisce un metodo print e lo cast.

0

Uso JMX per annullare la distribuzione e le classi di ridistribuzione.

Problemi correlati