Maison >Java >javaDidacticiel >Qu'est-ce que le mécanisme de réflexion Java ? Comment utiliser le mécanisme de réflexion Java

Qu'est-ce que le mécanisme de réflexion Java ? Comment utiliser le mécanisme de réflexion Java

不言
不言original
2018-09-20 14:55:533006parcourir

Le contenu de cet article porte sur ce qu'est le mécanisme de réflexion Java ? La méthode d'utilisation du mécanisme de réflexion Java a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer, j'espère qu'elle vous sera utile.

En parlant du mécanisme de réflexion, les personnes qui entrent en contact avec lui pour la première fois peuvent être confuses. Quelle réflexion ? Comment réfléchir ? A quoi sert la réflexion ? Ensuite, je parlerai de la machine de réflexion de Java dans cet article

Mais avant cela, il y a encore un problème qui doit être résolu La dynamique dans le nom du titre. Permettez-moi d'abord de vous présenter le langage dynamique et le langage statique

le langage statique

 Le langage statique est Langages dans lesquels le type de données de la variable peut être déterminé au moment de la compilation. La plupart des langages typés statiquement exigent que le type de données soit déclaré avant d'utiliser la variable. Par exemple : C++, Java, Delphi, C#, etc.

Langage dynamique

 Un langage dynamique est un langage qui détermine les types de données au moment de l'exécution . Il n'est pas nécessaire d'effectuer une déclaration de type avant d'utiliser une variable. Généralement, le type de la variable est le type de la valeur à laquelle elle est affectée. Par exemple, PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell, etc. et Langage dynamique signifient que le programme peut modifier sa structure pendant son exécution : de nouvelles fonctions peuvent être introduites, des fonctions existantes peuvent être supprimées et d'autres changements structurels.

En ce moment, vous avez peut-être des questions. Puisque Java est un langage statique, comment peut-il être dynamique ? La première est que Java a un mécanisme lié à la dynamique : Mécanisme de réflexion. Grâce au mécanisme de réflexion, Java peut charger, détecter et utiliser des classes complètement inconnues lors de la compilation lorsque le programme est en cours d'exécution, et peut générer des instances d'objet de classe associées, afin que ses méthodes puissent être appelées ou qu'une certaine valeur d'attribut puisse être modifié. JAVA peut donc aussi être considéré comme un langage semi-dynamique

Parlons du mécanisme de réflexion

 Concept du mécanisme de réflexion
Le mécanisme de réflexion en Java signifie qu'à l'état d'exécution, n'importe quelle classe peut connaître toutes les propriétés et méthodes de cette classe ; objet, n'importe laquelle de ses méthodes peut être appelée ; cette fonction d'obtention dynamique d'informations et d'appel dynamique de méthodes objet est appelée le mécanisme de réflexion du langage Java.

Le principe de la réflexion réside dans l'objet Classe

Jetez un œil au processus de chargement du programme

À partir de l'image, vous pouvez probablement voir à quoi sert la réflexion, puis parlons d'autres aspects de la réflexion

 API Reflection

  L'API Reflection est utilisée pour générer des informations sur les classes, les interfaces ou les objets dans la JVM.
  - Classe de classe : La classe principale de réflexion, qui peut obtenir les attributs, méthodes et autres informations de la classe.
  - Classe de champ : Une classe dans le package Java.lang.reflec, qui représente les variables membres de la classe et peut être utilisée pour obtenir et définir les valeurs d'attribut dans la classe.
  - Classe de méthode  : Une classe dans le package Java.lang.reflec qui représente la méthode de la classe. Elle peut être utilisée pour obtenir des informations sur la méthode ou exécuter des méthodes dans la classe.
  - Classe Constructeur : Une classe dans le package Java.lang.reflec, représentant la méthode de construction de la classe.

Parlons de la façon d'utiliser la réflexion  

Étapes

  • Récupérez l'objet Class de la classe que vous souhaitez utiliser

  • Appelez la méthode dans la classe Class

  • Utilisez l'API Reflection pour exploiter ces informations

2. Obtenez la méthode de l'objet Class

//假设我们有一个Student类
方法一、(推荐)
    Class clas = Class.forName("first.Student");//“”里写的是类的全路径

方法二、
    Student stu = new Student();
    Class clas = stu.getClass();

方法三、
    Class clas = Student.Class;

Vous pouvez essayer d'utiliser deux méthodes différentes pour obtenir clas1 et clas2, puis System.ou.println(clas1==clas2) pour voir ce qui sera affiché. La raison est dans l'image

<.>3. Obtenez la structure Méthodes, champs, méthodes principales et appelez

Student.java

public class Student {
    public String name;
    protected int age;
    char sex;
    private String phoneNum;
    
    public static void main(String[] args) {

        System.out.println("main方法执行了。。。");

    }
    //---------------构造方法-------------------
    Student(String str) {
        System.out.println("(默认)的构造方法 s = " + str);
    }

    // 无参构造方法
    public Student() {
        System.out.println("调用了公有、无参构造方法执行了。。。");
    }

    // 有一个参数的构造方法
    public Student(char name) {

        System.out.println("姓名:" + name);
    }

    // 有多个参数的构造方法
    public Student(String name, int age) {
        this.name=name;this.age=age;
        System.out.println("姓名:" + name + "年龄:" + age);// 这的执行效率有问题,以后解决。
    }

    // 受保护的构造方法
    protected Student(boolean n) {
        System.out.println("受保护的构造方法 n = " + n);
    }

    // 私有构造方法
    private Student(int age) {
        System.out.println("私有的构造方法   年龄:" + age);
    }
    
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", sex=" + sex
                + ", phoneNum=" + phoneNum + "]";
    }
}

Constructors.java(构造方法)

package first;

import java.lang.reflect.Constructor;

public class Constructors {
    public static void main(String[] args) throws Exception {
        
        Class clas=Class.forName("first.Student");
        
        System.out.println("所有公有构造方法");
        Constructor[] conArry=clas.getConstructors();
        for(int i=0;i<conArry.length;i++) {
            System.out.println(conArry[i]);
        }
        
        System.out.println("所有的构造方法");
        conArry=clas.getDeclaredConstructors();
        for(int i=0;i<conArry.length;i++) {
            System.out.println(conArry[i]);
        }
        
        System.out.println("获取公有无参的构造方法");
        Constructor con=clas.getConstructor(null);
        System.out.println("con="+con);
        Object obj=con.newInstance();
        
        System.out.println("获取私有构造方法,并调用");
        con=clas.getDeclaredConstructor(char.class);
        System.out.println(con);
        //con.setAccessible(true);//暴力访问,针对private方法和字段时使用
        obj=con.newInstance(&#39;a&#39;);//创建对象
    }
}

输出

所有公有构造方法
public first.Student(char)
public first.Student()
public first.Student(java.lang.String,int)
所有的构造方法
protected first.Student(boolean)
private first.Student(int)
public first.Student(char)
public first.Student()
first.Student(java.lang.String)
public first.Student(java.lang.String,int)
获取公有无参的构造方法
con=public first.Student()
调用了公有、无参构造方法执行了。。。
获取私有构造方法,并调用
public first.Student(char)
姓名:a

Fields.java(字段)

package first;
import java.lang.reflect.Field;
public class Fields {
    public static void main(String[] args)throws Exception {
        // TODO Auto-generated method stub
        Class StuClass=Class.forName("first.Student");
        
        System.out.println("获取所有公有的字段");
        Field[] fieldArry=StuClass.getFields();
        for(Field f:fieldArry) {
            System.out.println(f);
        }
        System.out.println("获取所有的字段(包括私有、受保护、默认的)");
        fieldArry=StuClass.getDeclaredFields();
        for(Field f:fieldArry) {
            System.out.println(f);
        }
        System.out.println("获取公有字段并调用");
        Field f = StuClass.getField("name");
        System.out.println(f);
        Object obj=StuClass.getConstructor().newInstance();
        StuClass.getConstructor(String.class,int.class).newInstance("a",10);
        f.set(obj, "b");
        Student stu=(Student)obj;
        System.out.println(stu.name);
        
        System.out.println("获取私有字段并调用");
        f = StuClass.getDeclaredField("phoneNum");
        System.out.println(f);
        f.setAccessible(true);//暴力反射,解除私有限定
        f.set(obj, "18888889999");
        System.out.println("验证电话:" + stu);
    }
}

输出

获取所有公有的字段
public java.lang.String first.Student.name
获取所有的字段(包括私有、受保护、默认的)
public java.lang.String first.Student.name
protected int first.Student.age
char first.Student.sex
private java.lang.String first.Student.phoneNum
获取公有字段并调用
public java.lang.String first.Student.name
调用了公有、无参构造方法执行了。。。
姓名:a年龄:10
b
获取私有字段并调用
private java.lang.String first.Student.phoneNum
验证电话:Student [name=b, age=0, sex=

Main.java

package first;
import java.lang.reflect.Method;
public class Main {
    public static void main(String[] args) {
        try {
            // 1、获取Student对象的字节码
            Class clazz = Class.forName("first.Student");

            // 2、获取main方法

            Method methodMain = clazz.getMethod("main", String[].class);// 第一个参数:方法名称,第二个参数:方法形参的类型,

            // 3、调用main方法
            // methodMain.invoke(null, new String[]{"a","b","c"});
            // 第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组
            // 这里拆的时候将 new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
            methodMain.invoke(null, (Object) new String[] {});// 方式一
            // methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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