2012-01-24 5 views
6

Durante lo studio di 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.Differenza tra Reflection e Late Binding in java con esempi in tempo reale

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

Thanks ..

risposta

2

tardiva (noto anche come la spedizione dinamica) non ha bisogno di riflessione - ha ancora bisogno di sapere che membro di legarsi in modo dinamico per al momento della compilazione (cioè la firma del il membro è noto in fase di compilazione), anche se il binding ai membri sottoposti a override avviene in fase di esecuzione.

Quando si fa riflessione, non si sa nemmeno che membro che si sta utilizzando (nemmeno il nomeè noto al momento della compilazione, per non parlare della firma) - tutto accade a run- tempo, quindi è molto più lento.

+0

Non sono sicuro delle prestazioni è davvero la dimensione migliore per prendere in considerazione quando si confrontano tali caratteristiche diverse di una lingua, hanno lo scopo di risolvere i problemi differenti ... –

3

Java utilizza l'associazione tardiva per supportare il polimorfismo; il che significa che la decisione su quale dei molti metodi dovrebbe essere usato viene posticipata 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(); 
    } 
} 

riflessione viene utilizzato invece per descrivere 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 un sacco di cose molto interessanti in fase di esecuzione.

Un bel spiegazione di riflessione è qui: What is reflection and why is it useful?

2

esempi del mondo reale:

Se si genera il progetto con jdesktop 0.8, ma nave con jdesktop 0.9, il codice sarà comunque utilizzare le funzioni di 0,9, perché sfrutta l'associazione tardiva, ovvero il codice che il codice chiama è la versione caricata dal programma di caricamento classi, indipendentemente dalla versione con cui è stato compilato. (Questo è in contrasto con i linker, che incorporano la versione in fase di compilazione del codice chiamato nell'applicazione.)

Per la riflessione, diciamo che stai cercando di scegliere come target Java 1.5 e 1.6, ma vuoi utilizzare i componenti della scheda in 1.6 se sono disponibili, verificherete la loro presenza utilizzando la riflessione sulla classe JTabbedPane per trovare il metodo setTabComponentAt. In questo caso stai costruendo contro Java 1.5, che non ha affatto queste caratteristiche, quindi non puoi chiamarle direttamente o la compilazione fallirà. Tuttavia se sul sistema dell'utente finale ci si trova a correre contro 1.6 (l'associazione tardiva entra in gioco qui) è possibile utilizzare la riflessione per chiamare metodi che non esistevano in 1.5.

Sono correlati; molti usi della riflessione si basano sul binding tardivo per essere utili, ma sono aspetti fondamentalmente diversi della lingua e della sua implementazione.

1

Un problema importante affrontato da "Late Binding" è il polimorfismo, ovvero il richiamo del metodo overriden corretto lungo la gerarchia di classi viene determinato durante il tempo di esecuzione, non durante la compilazione.Reflection è la funzione per raccogliere e manipolare le informazioni sugli oggetti durante l'esecuzione. Per esempio. puoi ottenere tutti gli attributi o i nomi dei metodi di un oggetto usando il suo attributo 'Classe' durante il runtime e chiamare quei metodi o manipolarne gli attributi.

Nel codice seguente è possibile creare dinamicamente un nuovo oggetto mediante la riflessione (vedere come il costruttore viene richiamato e utilizzato utilizzando una classe, invece di utilizzare semplicemente qualcosa come oggetto obj = new MyClass ("MyInstance")). In modo simile è possibile accedere ad altre forme, metodi e attributi del costruttore. Per ulteriori informazioni sulla riflessione in visita 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"); 
 
0

Non sono d'accordo con la maggior parte delle risposte qui -

tutti chiamano ciò che Java fa in termini di azzeramento in su un'implementazione di metodo in fase di esecuzione il più tardi vincolante, ma a mio avviso non è corretto usare il termine "late binding" per ciò che fa java.

L'associazione tardiva non implica assolutamente alcun controllo su una chiamata al metodo in fase di compilazione e nessun errore di compilazione se il metodo non esiste.

Java tuttavia genererà un errore di compilazione se il metodo non esiste da qualche parte nella gerarchia di tipi del tipo che qualifica la chiamata al metodo (essendo un po 'approssimativo quando descrive il comportamento qui). Questo non è un legame tardivo tradizionale puro. Cosa fa Java in una normale chiamata di metodo non statica non privata non definitiva sarebbe meglio definita come dispacciamento dinamico.
Tuttavia, se si utilizza reflection in Java, Java esegue il binding in ritardo puro in quanto il compilatore non può semplicemente 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(); 
     } 
     } 
}