2013-04-12 25 views
17

Ho un metodo statico in qualche codice legacy, che viene chiamato da più client. Ovviamente non ho opzioni per sovrascriverlo o modificare il comportamento tramite l'iniezione di dipendenza. Non sono autorizzato a modificare la classe esistente.Come modificare il comportamento del metodo attraverso la riflessione?

Quello che voglio fare ora è cambiare il comportamento (quel metodo - con la stessa firma e tipo di ritorno) usando il riflesso.

È possibile? In caso contrario, qualche schema di progettazione può salvarmi?

Grazie!

MODIFICA: C'è una certa confusione su cosa posso modificare/modificare. Non posso modificare alcuna classe/metodo esistente, ma posso aggiungere più classi al progetto. Il meglio che posso fare con le classi esistenti è annotarle. Tutto ciò per evitare di rompere qualsiasi cosa nel codice esistente - il che significa un ciclo completo di test per un grande progetto.

MODIFICA 2: java.lang.Instrumentation non è disponibile per Android - oppure suona bene!

+0

Perché la riflessione? –

+3

Non sei autorizzato a cambiarlo, ma sei autorizzato a modificarlo tramite la riflessione? Sembra molto più rischioso. – Keppil

+0

Penso che questo finirà in un incubo di manutenzione. Il codice giace a chiunque legga. Vai e ottieni l'approvazione per cambiare classe. – SpaceTrucker

risposta

18

Suona come un requisito strano ...

In ogni caso, la riflessione non consente di modificare il comportamento del codice, si può solo esplorare codice corrente, richiamare i metodi e constuctors, valori dei campi di modifica, quel genere di cose.

Se si desidera modificare effettivamente il comportamento di un metodo, è necessario utilizzare una libreria di manipolazione bytecode come ASM. Ma questo non sarà molto facile, probabilmente non è una buona idea ...

modelli che potrebbero aiutarvi:

  • Se la classe non è definitiva ed è possibile modificare i clienti, estendere la classe esistente e sovraccaricare il metodo, con il tuo comportamento desiderato. Modifica: funzionerebbe solo se il metodo non fosse statico! programmazione
  • Aspetto: aggiungere intercettori per il metodo che utilizza AspectJ

In ogni caso, la cosa più logica da fare sarebbe quella di trovare un modo per modificare la classe, il lavoro-around esistenti sarà solo rendere il codice più complicato e più difficile da mantenere.

Buona fortuna.

+0

Il metodo statico non può essere sovrascritto. Mi chiedo se la riflessione può cambiare i valori del campo, perché non i metodi! – SlowAndSteady

+0

Sono nuovo di AOP. Esplorandolo ora! – SlowAndSteady

+0

Hai ragione sul metodo che è statico, ovviamente. Ho modificato la mia risposta di conseguenza. –

8

Immagino che si possa dare un'occhiata alla classe Instrumentation che ha un metodo redefineClasses(ClassDefintion classDefinition).

La ridefinizione può cambiare i corpi del metodo, il pool costante e gli attributi. La ridefinizione non deve aggiungere, rimuovere o rinominare campi o metodi, modificare le firme dei metodi o modificare l'ereditarietà.

Spero che questo aiuti.

Riferimenti: Javadoc

+0

Spiacente, ho dimenticato di aggiungere questo è Android. Non ho questa classe per usufruire :( – SlowAndSteady