Domanda

Cos’è la riflessione e perché è utile?

Sono particolarmente interessato a Java, ma presumo che i principi siano gli stessi in qualsiasi linguaggio.

È stato utile?

Soluzione

Il nome riflessione viene utilizzato per descrivere il codice che è in grado di ispezionare altro codice nello stesso sistema (o se stesso).

Ad esempio, supponiamo di avere un oggetto di tipo sconosciuto in Java e di voler chiamare un metodo "doSomething" su di esso, se ne esiste uno.Il sistema di tipizzazione statica di Java non è realmente progettato per supportare questo a meno che l'oggetto non sia conforme a un'interfaccia conosciuta, ma utilizzando la riflessione, il tuo codice può guardare l'oggetto e scoprire se ha un metodo chiamato "faiSomething" e quindi chiamarlo se lo desideri volere.

Quindi, per darti un esempio di codice in Java (immagina che l'oggetto in questione sia foo):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

Un caso d'uso molto comune in Java è l'utilizzo con le annotazioni.JUnit 4, ad esempio, utilizzerà la riflessione per cercare nelle classi i metodi contrassegnati con l'annotazione @Test e quindi li chiamerà durante l'esecuzione del test unitario.

Ci sono alcuni buoni esempi di riflessione da cui iniziare http://docs.oracle.com/javase/tutorial/reflect/index.html

E infine, sì, i concetti sono più o meno simili in altri linguaggi di tipo statico che supportano la riflessione (come C#).Nei linguaggi tipizzati dinamicamente, il caso d'uso descritto sopra è meno necessario (poiché il compilatore consentirà di chiamare qualsiasi metodo su qualsiasi oggetto, fallendo in fase di esecuzione se non esiste), ma il secondo caso di ricerca di metodi contrassegnati o lavorare in un certo modo è ancora comune.

Aggiornamento da un commento:

La capacità di ispezionare il codice nel sistema e vedere i tipi di oggetti non è la riflessione, ma piuttosto il tipo di introspezione.La riflessione è quindi la capacità di apportare modifiche in fase di esecuzione facendo uso dell'introspezione.La distinzione è necessaria qui poiché alcune lingue supportano l'introspezione, ma non supportano la riflessione.Uno di questi esempi è C ++

Altri suggerimenti

Riflessione è la capacità di un linguaggio di ispezionare e chiamare dinamicamente classi, metodi, attributi, ecc.in fase di esecuzione.

Ad esempio, tutti gli oggetti in Java hanno il metodo getClass(), che ti consente di determinare la classe dell'oggetto anche se non la conosci in fase di compilazione (ad es.se lo hai dichiarato come an Object) - questo potrebbe sembrare banale, ma tale riflessione non è possibile in linguaggi meno dinamici come C++.Gli usi più avanzati consentono di elencare e chiamare metodi, costruttori, ecc.

La riflessione è importante poiché consente di scrivere programmi che non devono "conoscere" tutto in fase di compilazione, rendendoli più dinamici, poiché possono essere collegati insieme in fase di esecuzione.Il codice può essere scritto su interfacce conosciute, ma le classi effettive da utilizzare possono essere istanziate utilizzando la riflessione dai file di configurazione.

Molti framework moderni utilizzano ampiamente la riflessione proprio per questo motivo.Anche la maggior parte degli altri linguaggi moderni utilizza la riflessione e nei linguaggi di scripting (come Python) sono ancora più strettamente integrati, poiché sembra più naturale all'interno del modello di programmazione generale di quei linguaggi.

Uno dei miei usi preferiti della riflessione è il metodo di dump Java riportato di seguito.Prende qualsiasi oggetto come parametro e utilizza l'API di riflessione Java per stampare ogni nome e valore di campo.

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public static String dump(Object o, int callCount) {
    callCount++;
    StringBuffer tabs = new StringBuffer();
    for (int k = 0; k < callCount; k++) {
        tabs.append("\t");
    }
    StringBuffer buffer = new StringBuffer();
    Class oClass = o.getClass();
    if (oClass.isArray()) {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("[");
        for (int i = 0; i < Array.getLength(o); i++) {
            if (i < 0)
                buffer.append(",");
            Object value = Array.get(o, i);
            if (value.getClass().isPrimitive() ||
                    value.getClass() == java.lang.Long.class ||
                    value.getClass() == java.lang.String.class ||
                    value.getClass() == java.lang.Integer.class ||
                    value.getClass() == java.lang.Boolean.class
                    ) {
                buffer.append(value);
            } else {
                buffer.append(dump(value, callCount));
            }
        }
        buffer.append(tabs.toString());
        buffer.append("]\n");
    } else {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("{\n");
        while (oClass != null) {
            Field[] fields = oClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                buffer.append(tabs.toString());
                fields[i].setAccessible(true);
                buffer.append(fields[i].getName());
                buffer.append("=");
                try {
                    Object value = fields[i].get(o);
                    if (value != null) {
                        if (value.getClass().isPrimitive() ||
                                value.getClass() == java.lang.Long.class ||
                                value.getClass() == java.lang.String.class ||
                                value.getClass() == java.lang.Integer.class ||
                                value.getClass() == java.lang.Boolean.class
                                ) {
                            buffer.append(value);
                        } else {
                            buffer.append(dump(value, callCount));
                        }
                    }
                } catch (IllegalAccessException e) {
                    buffer.append(e.getMessage());
                }
                buffer.append("\n");
            }
            oClass = oClass.getSuperclass();
        }
        buffer.append(tabs.toString());
        buffer.append("}\n");
    }
    return buffer.toString();
}

Usi della riflessione

La riflessione viene comunemente utilizzata dai programmi che richiedono la capacità di esaminare o modificare il comportamento di runtime delle applicazioni in esecuzione nella Java virtual machine.Questa è una funzionalità relativamente avanzata e dovrebbe essere utilizzata solo da sviluppatori che hanno una conoscenza approfondita dei fondamenti del linguaggio.Tenendo presente questo avvertimento, la riflessione è una tecnica potente e può consentire alle applicazioni di eseguire operazioni che altrimenti sarebbero impossibili.

Funzionalità di estensibilità

Un'applicazione può utilizzare classi esterne definite dall'utente creando istanze di oggetti estensibilità utilizzando i relativi nomi completi.Browser di classe e ambienti di sviluppo visivo Un browser di classe deve essere in grado di elencare i membri delle classi.Gli ambienti di sviluppo visivo possono trarre vantaggio dall'utilizzo delle informazioni sul tipo disponibili nella riflessione per aiutare lo sviluppatore a scrivere il codice corretto.I debugger e gli strumenti di test devono essere in grado di esaminare i membri privati ​​nelle classi.I test cablaggio possono utilizzare la riflessione per chiamare sistematicamente un set di API rilevabili definito su una classe, per garantire un elevato livello di copertura del codice in una suite di test.

Inconvenienti della riflessione

La riflessione è potente, ma non dovrebbe essere usata indiscriminatamente.Se è possibile eseguire un'operazione senza utilizzare la riflessione, è preferibile evitare di utilizzarla.È necessario tenere presenti le seguenti preoccupazioni quando si accede al codice tramite riflessione.

  • Spese generali delle prestazioni

Poiché la riflessione coinvolge tipi risolti dinamicamente, alcune ottimizzazioni della Java virtual machine non possono essere eseguite.Di conseguenza, le operazioni riflessive hanno prestazioni più lente rispetto alle loro controparti non riflessive e dovrebbero essere evitate nelle sezioni di codice che vengono richiamate frequentemente nelle applicazioni sensibili alle prestazioni.

  • Restrizioni di sicurezza

La riflessione richiede un'autorizzazione di runtime che potrebbe non essere presente durante l'esecuzione con un gestore della sicurezza.Ciò è una considerazione importante per il codice che deve essere eseguito in un contesto di sicurezza limitato, come in un'applet.

  • Esposizione di elementi interni

Poiché la riflessione consente al codice di eseguire operazioni che sarebbero illegali nel codice non riflettente, come l'accesso a campi e metodi privati, l'uso della riflessione può provocare effetti collaterali imprevisti, che potrebbero rendere il codice non funzionante e distruggerne la portabilità.Il codice riflessivo rompe le astrazioni e quindi può modificare il comportamento con gli aggiornamenti della piattaforma.

fonte: L'API di riflessione

La riflessione è un meccanismo chiave per consentire a un'applicazione o a un framework di funzionare con codice che potrebbe non essere stato ancora scritto!

Prendi ad esempio il tuo tipico file web.xml.Questo conterrà un elenco di elementi servlet, che contengono elementi di classe servlet nidificati.Il contenitore servlet elaborerà il file web.xml e creerà una nuova istanza di ciascuna classe servlet attraverso la riflessione.

Un altro esempio potrebbe essere l'API Java per l'analisi XML (JAXP).Dove un provider di parser XML è "collegato" tramite proprietà di sistema note, che vengono utilizzate per costruire nuove istanze attraverso la riflessione.

E infine, l'esempio più completo è Primavera che utilizza la riflessione per creare i suoi bean e per il suo uso massiccio di proxy

Non tutte le lingue supportano la riflessione, ma i principi sono solitamente gli stessi nelle lingue che la supportano.

La riflessione è la capacità di "riflettere" sulla struttura del proprio programma.O più concreto.Per esaminare gli oggetti e le classi di cui disponi e ottenere a livello di codice informazioni sui metodi, sui campi e sulle interfacce che implementano.Puoi anche guardare cose come le annotazioni.

È utile in moltissime situazioni.Ovunque tu voglia essere in grado di collegare dinamicamente le classi al tuo codice.Molti mappatori relazionali di oggetti utilizzano la riflessione per essere in grado di istanziare oggetti dai database senza sapere in anticipo quali oggetti utilizzeranno.Le architetture plug-in sono un altro ambito in cui la riflessione è utile.Essere in grado di caricare dinamicamente il codice e determinare se sono presenti tipi che implementano l'interfaccia giusta da utilizzare come plug-in è importante in queste situazioni.

La riflessione consente la creazione di istanze di nuovi oggetti, l'invocazione di metodi e operazioni get/set su variabili di classe in modo dinamico in fase di esecuzione senza avere una conoscenza preliminare della sua implementazione.

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

Nell'esempio precedente il parametro null è l'oggetto su cui si desidera invocare il metodo.Se il metodo è statico, fornisci null.Se il metodo non è statico, durante l'invocazione è necessario fornire un'istanza MyObject valida anziché null.

Reflection ti consente anche di accedere a membri/metodi privati ​​di una classe:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

.

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • Per l'ispezione delle classi (nota anche come introspezione) non è necessario importare il pacchetto di riflessione (java.lang.reflect).È possibile accedere ai metadati della classe tramite java.lang.Class.

La Reflection è un'API molto potente ma potrebbe rallentare l'applicazione se utilizzata in eccesso, poiché risolve tutti i tipi in fase di runtime.

Esempio :
Prendi ad esempio un'applicazione remota che fornisce alla tua applicazione un oggetto che ottieni utilizzando i loro metodi API.Ora, in base all'oggetto, potrebbe essere necessario eseguire una sorta di calcolo.
Il provider garantisce che l'oggetto può essere di 3 tipi e dobbiamo eseguire il calcolo in base al tipo di oggetto.
Quindi potremmo implementare in 3 classi, ciascuna contenente una logica diversa. Ovviamente le informazioni sull'oggetto sono disponibili in runtime, quindi non è possibile codificare staticamente per eseguire il calcolo, quindi la riflessione viene utilizzata per istanziare l'oggetto della classe richiesto per eseguire il calcolo in base a oggetto ricevuto dal provider.

Java Reflection è abbastanza potente e può essere molto utile.Java Reflection lo rende possibile per ispezionare classi, interfacce, campi e metodi in fase di runtime, senza conoscere i nomi delle classi, dei metodi, ecc.in fase di compilazione.È anche possibile istanziare nuovi oggetti, invocare metodi e ottenere/impostare valori di campo utilizzando la riflessione.

Un rapido esempio di Java Reflection per mostrarti come appare l'utilizzo della riflessione:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

In questo esempio si ottiene l'oggetto Class dalla classe denominata MyObject.Usando l'oggetto classe l'esempio ottiene un elenco dei metodi in quella classe, itera i metodi e stampa i loro nomi.

Come funziona esattamente tutto questo è spiegato qui

Modificare:Dopo quasi 1 anno sto modificando questa risposta poiché durante la lettura della riflessione ho ottenuto alcuni altri usi di Reflection.

  • Spring utilizza la configurazione del bean come:


<bean id="someID" class="com.example.Foo">
    <property name="someField" value="someValue" />
</bean>

Quando il contesto Spring elabora questo elemento < bean >, utilizzerà Class.forName(String) con l'argomento "com.example.Foo" per istanziare quella Classe.

Utilizzerà quindi nuovamente la riflessione per ottenere il setter appropriato per l'elemento < property > e impostarne il valore sul valore specificato.

  • Junit utilizza Reflection soprattutto per testare metodi privati/protetti.

Per i metodi privati,

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

Per i campi privati,

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

Secondo la mia comprensione:

La riflessione consente al programmatore di accedere dinamicamente alle entità nel programma.cioè.durante la codifica di un'applicazione, se il programmatore non è a conoscenza di una classe o dei suoi metodi, può utilizzare tale classe in modo dinamico (in fase di esecuzione) utilizzando la riflessione.

Viene spesso utilizzato in scenari in cui il nome di una classe cambia frequentemente.Se si verifica una situazione del genere, è complicato per il programmatore riscrivere l'applicazione e cambiare ripetutamente il nome della classe.

Invece, utilizzando la riflessione, è necessario preoccuparsi della possibile modifica del nome della classe.

Riflessione è un'API utilizzata per esaminare o modificare il comportamento di metodi, classi, interfacce in fase di esecuzione.

  1. Le classi richieste per la riflessione sono fornite di seguito java.lang.reflect package.
  2. La riflessione ci fornisce informazioni sulla classe a cui appartiene un oggetto e anche sui metodi di quella classe che possono essere eseguiti utilizzando l'oggetto.
  3. Attraverso la riflessione possiamo invocare metodi in fase di esecuzione indipendentemente dallo specificatore di accesso utilizzato con essi.

IL java.lang E java.lang.reflect i pacchetti forniscono classi per la riflessione Java.

Riflessione può essere utilizzato per ottenere informazioni su:

  1. Classe IL getClass() Il metodo viene utilizzato per ottenere il nome della classe a cui appartiene un oggetto.

  2. Costruttori IL getConstructors() Il metodo viene utilizzato per ottenere i costruttori pubblici della classe a cui appartiene un oggetto.

  3. Metodi IL getMethods() Il metodo viene utilizzato per ottenere i metodi pubblici della classe a cui appartiene un oggetto.

IL API di riflessione è utilizzato principalmente in:

IDE (ambiente di sviluppo integrato) ad es.Eclipse, MyEclipse, NetBeans ecc.
Debugger e strumenti di test ecc.

Vantaggi dell'utilizzo della riflessione:

Caratteristiche di estensibilità: Un'applicazione può utilizzare classi esterne definite dall'utente creando istanze di oggetti estensibilità utilizzando i relativi nomi completi.

Strumenti di debug e test: I debugger utilizzano la proprietà di riflessione per esaminare i membri privati ​​delle classi.

Svantaggi:

Spese generali delle prestazioni: Le operazioni riflessive hanno prestazioni più lente rispetto alle loro controparti non riflessive e dovrebbero essere evitate nelle sezioni di codice che vengono chiamate frequentemente nelle applicazioni sensibili alle prestazioni.

Esposizione di interni: Il codice riflessivo rompe le astrazioni e quindi può modificare il comportamento con gli aggiornamenti della piattaforma.

Rif: Riflessione Java javarevisited.blogspot.in

Reflection è un insieme di funzioni che ti permettono di accedere alle informazioni di runtime del tuo programma e di modificarne il comportamento (con alcune limitazioni).

È utile perché ti permette di modificare il comportamento di runtime in base alle metainformazioni del tuo programma, ovvero puoi controllare il tipo restituito di una funzione e cambiare il modo in cui gestisci la situazione.

In C# ad esempio puoi caricare un assembly (un .dll) in runtime ed esaminarlo, navigando tra le classi ed intraprendendo azioni in base a ciò che hai trovato.Ti consente anche di creare un'istanza di una classe in fase di runtime, invocare il suo metodo, ecc.

Dove può essere utile?Non è utile ogni volta ma per situazioni concrete.Ad esempio puoi usarlo per ottenere il nome della classe per scopi di login, per creare dinamicamente gestori di eventi in base a quanto specificato su un file di configurazione e così via...

semplice esempio di riflessione.In una partita a scacchi, non si sa cosa verrà spostato dall'utente in fase di esecuzione.la riflessione può essere utilizzata per chiamare metodi già implementati in fase di esecuzione.

public class Test {

    public void firstMoveChoice(){
        System.out.println("First Move");
    } 
    public void secondMOveChoice(){
        System.out.println("Second Move");
    }
    public void thirdMoveChoice(){
        System.out.println("Third Move");
    }

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
        Test test = new Test();
        Method[] method = test.getClass().getMethods();
        //firstMoveChoice
        method[0].invoke(test, null);
        //secondMoveChoice
        method[1].invoke(test, null);
        //thirdMoveChoice
        method[2].invoke(test, null);
    }

}

La riflessione è lasciare che gli oggetti vedano il loro aspetto.Questo argomento non sembra avere nulla a che fare con la riflessione.In realtà, questa è la capacità di "autoidentificarsi".

La riflessione stessa è una parola per quei linguaggi che non hanno la capacità di auto-conoscenza e auto-percezione come Java e C#.Poiché non hanno la capacità di conoscenza di sé, quando vogliamo osservare come appare, dobbiamo avere un'altra cosa su cui riflettere su come appare.Eccellenti linguaggi dinamici come Ruby e Python possono percepire il riflesso dei propri senza l'aiuto di altri individui.Possiamo dire che l'oggetto di Java non può percepire come appare senza uno specchio, che è un oggetto della classe riflessione, ma un oggetto in Python può percepirlo senza uno specchio.Ecco perché abbiamo bisogno di una riflessione in Java.

Voglio solo aggiungere qualche punto a tutto ciò che è stato elencato.

Con API di riflessione puoi scrivere universale toString() metodo per qualsiasi oggetto.

È utile per il debug.

Ecco qualche esempio:

class ObjectAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object's class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}

Dalla documentazione Java pagina

java.lang.reflect Il pacchetto fornisce classi e interfacce per ottenere informazioni riflessive su classi e oggetti.La riflessione consente l'accesso programmatico alle informazioni sui campi, i metodi e i costruttori delle classi caricate e l'uso di campi, metodi e costruttori riflessi per operare sulle loro controparti sottostanti, entro limiti di sicurezza.

AccessibleObject consente la soppressione dei controlli di accesso, se necessario ReflectPermission è disponibile.

Lezioni in questo pacchetto, insieme a java.lang.Class ospitare applicazioni come debugger, interpreti, ispettori di oggetti, browser di classi e servizi come Object Serialization E JavaBeans che necessitano di accesso ai membri pubblici di un oggetto di destinazione (in base alla sua classe runtime) o ai membri dichiarati da una determinata classe

Include le seguenti funzionalità.

  1. Ottenere oggetti di classe,
  2. Esaminare le proprietà di una classe (campi, metodi, costruttori),
  3. Impostazione e acquisizione dei valori dei campi,
  4. Metodi di chiamata,
  5. Creazione di nuove istanze di oggetti.

dai un'occhiata a questo documentazione collegamento per i metodi esposti da Class classe.

Da questa articolo (di Dennis Sosnoski, Presidente, Sosnoski Software Solutions, Inc) e questo articolo (esplorazioni sulla sicurezza pdf):

Vedo notevoli inconvenienti rispetto all'utilizzo di Reflection

Utente di riflessione:

  1. Fornisce un modo molto versatile per collegare dinamicamente i componenti del programma
  2. È utile per creare librerie che funzionano con oggetti in modi molto generali

Svantaggi della riflessione:

  1. La riflessione è molto più lenta del codice diretto quando viene utilizzata per l'accesso a campi e metodi.
  2. Può oscurare ciò che sta realmente accadendo all'interno del tuo codice
  3. Aggirare il codice sorgente può creare problemi di manutenzione
  4. Il codice di riflessione è anche più complesso del corrispondente codice diretto
  5. Consente la violazione dei vincoli chiave di sicurezza Java come la protezione dell'accesso ai dati e la sicurezza del tipo

Abusi generali:

  1. Caricamento di classi riservate,
  2. Ottenere riferimenti a costruttori, metodi o campi di una classe ristretta,
  3. Creazione di nuove istanze di oggetti, invocazione di metodi, acquisizione o impostazione di valori di campo di una classe limitata.

Dai un'occhiata a questa domanda SE relativa all'abuso della funzionalità di riflessione:

Come leggo un campo privato in Java?

Riepilogo:

Anche l'uso non sicuro delle sue funzioni effettuato dall'interno di un codice di sistema può facilmente portare alla compromissione di una modalità di sicurezza Javal. Quindi usa questa funzione con parsimonia

Come suggerisce il nome stesso, riflette ciò che contiene, ad esempio il metodo della classe, ecc. Oltre a fornire funzionalità per invocare il metodo creando un'istanza dinamicamente in fase di runtime.

Viene utilizzato da molti framework e applicazioni sottobanco per invocare servizi senza conoscere effettivamente il codice.

Reflection ha molti usi.Quello con cui ho più familiarità è la possibilità di creare codice al volo.

CIOÈ:Classi dinamiche, funzioni, costruttori - Basato su qualsiasi dati (XML/array/SQL Risultati/hardcoded/ecc.)

Reflection ti dà la possibilità di scrivere codice più generico.Ti consente di creare un oggetto in fase di esecuzione e chiamare il suo metodo in fase di esecuzione.Quindi il programma può essere reso altamente parametrizzato.Consente inoltre di eseguire l'introspezione dell'oggetto e della classe per rilevarne le variabili e il metodo esposti al mondo esterno.

Voglio rispondere a questa domanda con un esempio.Prima di tutto Hibernate usi del progetto Reflection API generare CRUD istruzioni per colmare il divario tra l'applicazione in esecuzione e l'archivio di persistenza.Quando le cose cambiano nel dominio, il Hibernate deve conoscerli per persisterli nell'archivio dati e viceversa.

In alternativa funziona Lombok Project.Inserisce semplicemente il codice in fase di compilazione, determinando l'inserimento del codice nelle classi del dominio.(Penso che sia OK per getter e setter)

Hibernate scelto reflection perché ha un impatto minimo sul processo di compilazione di un'applicazione.

E da Java 7 abbiamo MethodHandles, che funziona come Reflection API.Nei progetti, per lavorare con i logger basta copiare e incollare il codice successivo:

Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());

Perché in questo caso è difficile commettere errori di battitura.

Poiché trovo che sia meglio spiegare con l'esempio e nessuna delle risposte sembra farlo ...

Un esempio pratico di utilizzo delle riflessioni sarebbe un Java Language Server scritto in Java o un PHP Language Server scritto in PHP, ecc.Language Server offre al tuo IDE funzionalità come il completamento automatico, il passaggio alla definizione, la guida contestuale, i tipi di suggerimenti e altro ancora.Per fare in modo che tutti i nomi dei tag (parole che possono essere completate automaticamente) corrispondano quando si preme, diciamo: TAB e mostrare tutti i suggerimenti, il Language Server deve ispezionare tutto ciò che riguarda la classe, inclusi i blocchi di documenti e i membri privati.Per questo è necessario un riflesso di detta classe.

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