Maison  >  Article  >  Java  >  Introduction à l'analyse de la réflexion Java

Introduction à l'analyse de la réflexion Java

高洛峰
高洛峰original
2017-03-09 19:05:401017parcourir

Ce document décrit l'analyse et l'introduction de la réflexion Java

1. Qu'est-ce que la réflexion ?
Depuis l'Encyclopédie Baidu, nous pouvons savoir que la réflexion Java est en cours d'exécution. Pour n'importe quelle classe, nous pouvons connaître toutes les propriétés et méthodes de cette classe, nous pouvons appeler n'importe laquelle de ses méthodes et propriétés ; peut modifier ses propriétés. Et c'est pourquoi Java est considéré comme dynamique (ou quasi-dynamique, pourquoi est-il dit quasi-dynamique, car la définition générale d'un langage dynamique est que lorsque le programme est en cours d'exécution, il permet à la structure du programme ou au type de variable de être modifié. Ce langage est appelé langage dynamique. De ce point de vue, Perl, Python et Ruby sont des langages dynamiques, et C, Java et C# ne sont pas des langages dynamiques.) Une propriété clé des langages.

2. Que peut faire la réflexion ?
Nous savons que le mécanisme de réflexion permet au programme d'obtenir les informations internes de toute classe avec un nom connu au moment de l'exécution, y compris ses modificateurs (modificateurs), ses champs (propriétés), ses méthodes (méthodes), etc., et peut être modifié au moment de l'exécution. Ensuite, nous pouvons écrire du code de manière plus flexible, et le code peut être assemblé au moment de l'exécution sans avoir besoin de liaison de code source entre les composants, réduisant ainsi le couplage du code ; il y a également l'implémentation de proxys dynamiques, etc. ; payé à une mauvaise utilisation de la réflexion Cela coûtera très cher !

3. Mise en œuvre spécifique de la réflexion

Ce qui suit est une personne de classe de base

package com.ys.reflex;
public class Person {
    //私有属性
    private String name = "Tom";
    //公有属性
    public int age = 18;
    //构造方法
    public Person() {    
    }
    //私有方法
    private void say(){
        System.out.println("private say()...");
    }
    //公有方法
    public void work(){
        System.out.println("public work()...");
    }
}

① Obtenez la classe. Les trois méthodes

//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
//  类型的对象,而我不知道你具体是什么类,用这种方法
  Person p1 = new Person();
  Class c1 = p1.getClass();
        
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
//  这说明任何一个类都有一个隐含的静态成员变量 class
  Class c2 = Person.class;
        
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
//   但可能抛出 ClassNotFoundException 异常
  Class c3 = Class.forName("com.ys.reflex.Person");

Il est à noter que : Une classe n'aura qu'une seule instance de Classe dans la JVM, c'est-à-dire le c1 que nous avons obtenu ci-dessus , c2 et c3 sont comparés avec des égaux et trouvés vrais

②, Obtenez les variables membres, les méthodes membres, les interfaces, les super classes, les constructeurs, etc. la classe Class

En regardant l'API, vous pouvez voir que Class a de nombreuses méthodes :

 getName() : Obtenez le nom complet de la classe.
GetFields() : récupère les attributs de type public de la classe.
 getDeclaredFields() : Récupère tous les attributs de la classe. Y compris les classes privées déclarées et héritées
 getMethods() : récupère la méthode de type public de la classe.
 getDeclaredMethods() : Récupère toutes les méthodes de la classe. Y compris les classes privées déclarées et héritées
 getMethod(String name, Class[] ParameterTypes) : récupère la méthode spécifique de la classe, le paramètre name spécifie le nom de la méthode et le paramètre paramètreTypes spécifie le type de paramètre de la méthode.
GetConstructors() : récupère le constructeur de type public de la classe.
 getConstructor(Class[] ParameterTypes) : récupère la méthode constructeur spécifique de la classe. Le paramètre ParameterTypes spécifie le type de paramètre de la méthode constructeur.
 newInstance() : Créez un objet de cette classe via le constructeur de la classe sans paramètres.

Nous utilisons un exemple pour démontrer de manière exhaustive la méthode ci-dessus :

//获得类完整的名字
String className = c2.getName();
System.out.println(className);//输出com.ys.reflex.Person
        
//获得类的public类型的属性。
Field[] fields = c2.getFields();
for(Field field : fields){
   System.out.println(field.getName());//age
}
        
//获得类的所有属性。包括私有的和继承类的
Field [] allFields = c2.getDeclaredFields();
for(Field field : allFields){
    System.out.println(field.getName());//name    age
}
        
//获得类的public类型的方法。这里包括 Object 类的一些方法
Method [] methods = c2.getMethods();
for(Method method : methods){
    System.out.println(method.getName());//work waid equls toString hashCode等
}
        
//获得类的所有方法。
Method [] allMethods = c2.getDeclaredMethods();
for(Method method : allMethods){
    System.out.println(method.getName());//work say
}
        
//获得指定的属性
Field f1 = c2.getField("age");
System.out.println(f1);
//获得指定的私有属性
Field f2 = c2.getDeclaredField("name");
//启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
f2.setAccessible(true);
System.out.println(f2);
                
//创建这个类的一个对象
Object p2 =  c2.newInstance();
//将 p2 对象的  f2 属性赋值为 Bob,f2 属性即为 私有属性 name
f2.set(p2,"Bob");
//使用反射机制可以打破封装性,导致了java对象的属性不安全。 
System.out.println(f2.get(p2)); //Bob
        
//获取构造方法
Constructor [] constructors = c2.getConstructors();
for(Constructor constructor : constructors){
    System.out.println(constructor.toString());//public com.ys.reflex.Person()
}

4. Résumé de la réflexion

L'utilisation flexible de la réflexion peut rendre notre code plus flexible, voici ce qu'il en est. un exemple de pilote d'enregistrement de code natif JDBC, la classe d'entité d'hibernate, l'AOP de Spring, etc. ont tous des implémentations de réflexion. Mais tout a deux faces. La réflexion augmentera également les performances et la complexité du système. Une utilisation raisonnable est la vérité !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn