Différence entre réflexion et reliure tardive dans Java avec des exemples en temps réel

StackOverflow https://stackoverflow.com/questions/8984633

  •  13-11-2019
  •  | 
  •  

Question

Tout en étudiant des tutoriels Java, la réflexion et la reliure tardive m'ont confondu.Dans certains didacticiels, ils ont écrit qu'ils sont tous deux identiques et qu'il n'y a aucune différence entre la réflexion et la reliure tardive.Mais d'autres tutoriels disent qu'il y a une différence.

Je suis confus, alors quelqu'un peut-il expliquer quelle réflexion et la reliure tardive sont en Java, et si possible, donnez-moi des exemples de monde réel des deux.

merci ..

Était-ce utile?

La solution

La reliure tardive (également appelée expédition dynamique) n'a pas besoin de réflexion - il doit toujours savoir quel membre pour se lier dynamiquement à au moment de la compilée (c.-à-d.La signature du membre est connue au moment de la compilation), même si la liaison à des membres remplacés se produit au moment de l'exécution.

Lors de la réflexion, vous ne savez même pas quel membre que vous utilisez (pas même le nom est connu à la compilée, sans parler de la signature)- tout arrive au moment de l'exécution, il est donc beaucoup plus lent.

Autres conseils

Java utilise une liaison tardive pour soutenir le polymorphisme;Ce qui signifie que la décision des nombreuses méthodes doit être utilisée est différée jusqu'au moment de l'exécution.

Prendre le cas de n classes mettant en œuvre une méthode abstraite d'une interface (ou d'une classe abstraite, 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 réflexion est utilisée à la place pour décrire le code qui est capable d'inspecter autre code, c'est-à-dire.Pour savoir quelles méthodes ou attributs sont disponibles dans une classe, appeler une méthode (ou charger une classe) par nom et faire beaucoup de choses très intéressantes à l'exécution.

Une très belle explication de réflexion est ici: Qu'est-ce que la réflexion etPourquoi est-ce utile?

Exemples du monde réel:

Si vous construisez votre projet avec JDESKTOP 0,8, mais expédiez avec JDESKTop 0.9, votre code utilisera toujours les fonctionnalités de 0,9, car il tire parti de la liaison tardif, c'est-à-dire que le code appelle votre code est la version chargée par le Chargeuse de classe, indépendamment de la version qu'elle a été compilée. (Ceci est opposé aux liaiseurs, qui incorporent la version de compilée du code appelé dans l'application.)

Pour la réflexion, disons que vous essayez de cibler Java 1.5 et 1.6, mais souhaitez utiliser les composants de l'onglet en 1.6 si elles sont disponibles, vous vérifierez leur présence en utilisant la réflexion sur la classe JTABDEDPANE pour trouver le générateur méthode. Dans ce cas, vous construisez contre Java 1.5, qui n'a pas du tout ces fonctionnalités, vous ne pouvez donc pas les appeler directement ou la compilée échouera. Toutefois, si sur le système de l'utilisateur final, vous recherchez 1,6 (la liaison tardif entre en jeu ici), vous pouvez utiliser la réflexion pour appeler des méthodes qui n'existaient pas en 1.5.

ils sont liés; De nombreuses utilisations de la réflexion s'appuient sur une liaison tardive à être utiles, mais elles sont fondamentalement différents des aspects de la langue et de sa mise en œuvre.

Un problème important qui est adressé par "la liaison tardive" est le polymorphisme, c'est-à-dire que l'appel de la méthode de la nervation appropriée le long de votre hiérarchie de classe est déterminé pendant la période d'exécution, pas pendant la compilation. La réflexion est la fonctionnalité pour rassembler et manipuler des informations sur vos objets pendant la période d'exécution. Par exemple. Vous pouvez obtenir tous les attributs ou tous les noms de méthodes d'un objet à l'aide de son attribut «classe» pendant l'exécution et appelez ces méthodes ou manipulez ses attributs.

Dans le code suivant, vous pouvez créer de manière dynamique un nouvel objet par le moyen de réflexion (voir la manière dont le constructeur est récupéré et accédé à l'aide d'une classe, au lieu d'utiliser simplement quelque chose comme objet obj= nouvelle myClass ("MyInstance")). De la même manière, il est possible d'accéder à d'autres formes de constructeur, méthodes et attributs. Pour plus d'informations sur la réflexion dans Java Visitez: http://java.sun.com/developer / TechnicalArtics / ALT / Réflexion /


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

Je dois être en désaccord avec la plupart des réponses ici -

Tout le monde appelle ce que Java fait en termes de mise à zéro dans une mise en œuvre de la méthode à l'exécution de la liaison tardive, mais à mon avis, il n'est pas correct d'utiliser le terme contraignant tardive pour ce que fait Java.

La liaison tardif implique absolument aucune vérification sur un appel de méthode au moment de la compilation et aucune erreur de compilation si la méthode n'existe pas.

Java Cependant, je lancera une erreur de compilée si la méthode n'existe pas quelque part dans la hiérarchie de type du type qualifiant l'appel de la méthode (étant quelque peu approximative lorsque vous décrivez le comportement ici).Ce n'est pas une liaison tardif traditionnelle pure. Ce que Java fait dans un appel de méthode non statique non final non privé normal serait mieux qualifié d'envoi dynamique.
Toutefois, si nous utilisons la réflexion en Java, Java effectue ensuite une liaison tardif puante lorsque le compilateur ne peut tout simplement pas vérifier si la méthode appelée existe ou non. Voici un exemple:

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();
        } 
       }
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top