Domanda

Durante lo studio dei tutorial Java, Reflection e Late Binding mi hanno confuso.In alcuni tutorial hanno scritto che sono entrambi uguali e che non c'è alcuna differenza tra Reflection e Late Binding.Ma altri tutorial dicono che c'è una differenza.

Sono confuso, quindi qualcuno può spiegare cosa sono Reflection e Late Binding in Java e, se possibile, darmi alcuni esempi reali di entrambi.

Grazie..

È stato utile?

Soluzione

Il legame tardivo (noto anche come spedizione dinamica) non ha bisogno di riflessione - deve ancora sapere quale membro a cui legare dinamicamente al tempo di compilazione (cioè la firma del membro è nota al tempo di compilazione), anche se il binding per i membri sovrascritti avviene in fase di esecuzione.

Quando si riflette, non lo sai nemmeno quale membro che stai usando (nemmeno il nome è noto al tempo di compilazione, figuriamoci la firma)- Tutto quanto Succede in tempo di esecuzione, quindi è molto più lento.

Altri suggerimenti

Java usa il legame tardivo per supportare il polimorfismo; Ciò significa che la decisione di quale dei molti metodi dovrebbe essere utilizzata è differita fino al runtime.

Prendi il caso di N classi che implementano un metodo astratto di un'interfaccia (o una classe astratta, FWIW).

public interface IMyInterface {

    public void doSomething();    
}

public class MyClassA implements IMyInterface {

    public void doSomething(){ ... }
}

public class MyClassB implements IMyInterface {

    public void doSomething(){ ... }
}

public class Caller {

    public void doCall(IMyInterface i){
        // which implementation of doSomething is called?
        // it depends on the type of i: this is late binding
        i.doSomething(); 
    }
}

La riflessione viene invece utilizzata per descrivere il codice che è in grado di ispezionare altro codice, cioè. Per sapere quali metodi o attributi sono disponibili in una classe, per chiamare un metodo (o caricare una classe) per nome e fare molte cose molto interessanti in fase di esecuzione.

Una spiegazione molto bella della riflessione è qui: Cos'è la riflessione e perché è utile?

Esempi del mondo reale:

Se crei il tuo progetto con jdesktop 0.8, ma lo spedisci con jdesktop 0.9, il tuo codice utilizzerà comunque le funzionalità 0.9, perché sfrutta l'associazione tardiva, ad es.il codice richiamato dal codice è la versione caricata dal caricatore di classi, indipendentemente dalla versione con cui è stato compilato.(Questo al contrario dei linker, che incorporano la versione in fase di compilazione del codice chiamato nell'applicazione.)

Per riflettere, supponiamo che tu stia cercando di indirizzare Java 1.5 e 1.6, ma desideri utilizzare i componenti scheda in 1.6 se sono disponibili, quindi controllerai la loro presenza utilizzando la riflessione sulla classe JTabbedPane per trovare il setTabComponentAt metodo.In questo caso stai costruendo su Java 1.5, che non ha affatto queste funzionalità, quindi non puoi chiamarle direttamente altrimenti la compilazione fallirà.Tuttavia, se sul sistema dell'utente finale ti ritrovi a correre contro 1.6 (qui entra in gioco l'associazione tardiva) puoi utilizzare la riflessione per chiamare metodi che non esistevano in 1.5.

Sono imparentati;molti usi della riflessione si basano sull'associazione tardiva per essere utili, ma sono aspetti fondamentalmente diversi del linguaggio e della sua implementazione.

Un problema importante che viene affrontato da "vincolo tardivo" è il polimorfismo, cioè che la chiamata del metodo di sovraccarico corretto lungo la tua classe heerachy viene determinato durante il tempo di esecuzione, non durante la compilation. La riflessione è la funzionalità per raccogliere e manipolare informazioni sui tuoi oggetti durante il tempo di esecuzione. Ad esempio, è possibile ottenere tutti gli attributi o i nomi dei metodi di un oggetto usando il suo attributo "classe" durante il runtime e chiamare tali metodi o manipolare i suoi attributi.

Nel seguente codice è possibile creare dinamicamente un nuovo oggetto per mezzo di riflessione (vedi come viene recuperato e acceduto al costruttore usando una classe, invece di usare semplicemente qualcosa come Object Obj = new Myclass ("MyInstance")). Allo stesso modo è possibile accedere ad altre forme, metodi e attributi del costruttore. Per ulteriori informazioni sulla riflessione nella visita di Java: http://java.sun.com/developer/technicalarticles/alt/reflection/


... in some method of some class ...
Class c = getClass();
Constructor ctor = c.getConstructor( String.class );
Object obj = ctor.newInstance( "MyInstance" );

Devo non essere d'accordo con la maggior parte delle risposte qui -

Tutti chiamano ciò che Java fa in termini di zero in un metodo implementazione in fase di esecuzione come vincolo tardivo, ma a mio avviso non è corretto usare il termine vincolo tardivo per ciò che Java fa.

Il legame tardivo implica assolutamente nessun controllo su una chiamata metodo al momento della compilazione e nessun errore di compilation se il metodo non esiste.

Java tuttavia lancerà un errore di compilazione se il metodo non esiste da qualche parte nella gerarchia del tipo del tipo che qualifica la chiamata del metodo (essendo in qualche modo approssimativo quando si descrivono il comportamento qui). Questo non è puro legame tardivo tradizionale. Ciò che Java fa in una chiamata normale non statica non statica non privata sarebbe meglio definito come spedizione dinamica.
Tuttavia, se utilizziamo il riflesso in Java, allora Java esegue un legame tardivo puro poiché il compilatore semplicemente non può verificare se il metodo chiamato esiste o meno. Ecco un esempio:

class A
{
    public void foo()
    {
        System.out.println("Foo from A");
    }
}

class B extends A
{
    public void foo()
    {
        System.out.println("Foo from B");
    }
}
public class C
{
   public static void main(String [] args)
    {
         A a=new A();
         B b=new B();
         A ref=null;
         Class ref1 = null;
         ref1 = b.getClass();
         ref.foo1();//will not compile because Java in this normal method
         //call does some compile time checks for method and method 
         //signature existence. NOT late binding in its pure form.
         try {
            ref1.getMethod("foo1").invoke(null); //will throw a 
            //NoSuchMethodException at runtime, but compiles perfectly even 
            //though foo1 does not exist. This is pure late binding.
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
       }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top