java的反射机制

java的反射机制

  1. 类加载器
  2. 反射

类加载器

类加载器的基本概念

当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

类加载器的过程

    加载----连接----初始化

类的加载时机

  1. 创建类的实例
  2. 访问类的静态变量,或者为静态变量赋值
  3. 调用类的静态方法
  4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
  5. 初始化某个类的子类
  6. 直接使用java.exe命令来运行某个主类

类加载器的分类

1.Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中

2.Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录

3.Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件

反射

反射的基本概念

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

获取字节码文件对象的三种方法

A:Object类的getClass()方法
B:数据类型的静态class属性
C:Class类的静态方法forName()
package com.wy.reflect1;

public class Student {
    private String name;
     int  age;
    public String gender;

    public Student(){}

     Student(String name){
        this.name = name;
    }

    protected Student(String name,int age){
        this.name = name;
        this.age = age;
    }

    private Student(String name,int age,String gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public void show(){
        System.out.println("public show");
    }

    protected void proShow(){
        System.out.println("protected show");

    }

    void voShow(){
        System.out.println("void show");
    }

    private void priShow(){
        System.out.println("private show");
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", gender=" + gender + "]";
    }


}

首先定义了一个Student类,下面的代码是使用三种方法获得Student的字节码文件对象。

package com.wy.reflect1;

public class ClassGetTest {
    public static void main(String[] args) {

        //获取字节码文件对象的第一种方式
        //Object类的getClass()方法
        Student s = new Student();
        Class cla1 = s.getClass();
        System.out.println(cla1);

        //获取字节码文件对象的第二种方式
        //数据类型的静态class属性
        Class cla2 = Student.class;
        System.out.println(cla2);
        System.out.println("The first and the second is equals? ");
        System.out.println(cla1 == cla2);
        //获取字节码文件的第三种方式
        //Class类的静态方法forName()
        try {
            Class cla3 = Class.forName("com.wy.reflect1.Student");

            System.out.println(cla3);
            System.out.println("The first and the third is equals? ");
            System.out.println(cla1 == cla3);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }
}

反射的使用步骤

class字节码文件对象 -- 去得到对应的成员对象 -- 通过该成员的对象调用方法使用。

**成员变量 Field
构造方法 Constructor
成员方法 Method**
*凡是加declared,就是什么类型都可以获取的;
凡是方法后面加s的都是获取多个*

通过反射获取构造方法

package com.wy.reflect1;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ConstructorTest {
    public static void main(String[] args) throws Exception {
        // 获取字节码文件对象的第一种方式
        // Object类的getClass()方法
        Student s = new Student();
        Class class1 = s.getClass();

        //1.通过反射获取构造方法 public Constructor[] getConstructors() 获取公共的构造方法 public
        Constructor[] cons = class1.getConstructors();
        System.out.println("getConstructors----------results are ");
        for (Constructor con : cons) {
            System.out.println(con);
        }
        //利用构造方法创建对象
        Constructor con = cons[0];
        try {
            Student stu = (Student) con.newInstance();
            stu.show();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有) public
        Constructor[] cons2 = class1.getDeclaredConstructors();
        System.out.println("getDeclaredConstructors----------------results are ");
        for (Constructor c : cons2) {
            System.out.println(c);
        }
        cons2[0].setAccessible(true);
        //取消访问修饰符限制的构造器创建对象
        Student stu2 = (Student) cons2[0].newInstance("wy",18,"woman");
        stu2.proShow();

        //Constructor getConstructor(Class... parameterTypes)
        Constructor con3 = class1.getDeclaredConstructor(String.class, int.class, String.class);
        System.out.println("getConstructor(String.class,int.class, String.class)-----------results are ");
        System.out.println(con3);
        //取消访问修饰符的限制
        con3.setAccessible(true);
        //利用取消访问修饰符的构造器创建对象
        Student stu3 = (Student) con3.newInstance("zl",28,"man");
        System.out.println(stu3);

    }
}

通过反射获取成员变量

package com.wy.reflect1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class FieldTest {
    /*
     * private String name;
     * int  age;
     * public String gender;
     */
    public static void main(String[] args) throws Exception {
        Class cla2 = Student.class;
        Constructor con = cla2.getConstructor();
        Student stu = (Student) con.newInstance();
        /*
        public Field[] getFields()获取公有的成员变量
          public Field[] getDeclaredFields()获取全部的成员变量,包括私有
          public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有
          public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的
          public void set(Object obj,Object value)给一个对象的一个字段设置一个值
          */

        //public Field[] getFields()获取公有的成员变量
        Field[] fields = cla2.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("------------------");
        //public Field[] getDeclaredFields()获取全部的成员变量,包括私有
        Field[] fields2 = cla2.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println(field);
        }
        //public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有
        Field f = cla2.getDeclaredField("name");
        f.setAccessible(true);
        f.set(stu, "wangying");
        System.out.println(stu);

    }
}

通过反射获取成员方法

package com.wy.reflect1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class MethodTest {
    public static void main(String[] args) throws Exception {
        Class cla3 = Class.forName("com.wy.reflect1.Student");
        Constructor con = cla3.getDeclaredConstructor(String.class,int.class);
        con.setAccessible(true);
        Student stu = (Student) con.newInstance("zl",18);

        Method[] methods = cla3.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        Method m = cla3.getDeclaredMethod("proShow");
        //调用这个方法
        /*
         * public Object invoke(Object obj,Object... args)
         * 参数1:执行m2这个方法的对象
         * 参数2:执行m2这个方法的时候,需要传入的参数
         */
        m.invoke(stu);
    }
}

java的反射到此……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值