黑马程序员技术交流社区

标题: 反射机制的学习 [打印本页]

作者: One丶Life    时间: 2015-11-22 20:19
标题: 反射机制的学习
1 反射机制

1、介绍
        JAVA反射机制实在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为JAVA反射机制。
        要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。
        通俗来讲,反射就是通过class文件对象,去使用该文件中的成员变量、构造方法、成员方法。
        Class类:
                成员变量:Field
                构造函数:Constructor
                成员方法:Method

2、获取calss文件对象的方式
    在开发中一般使用第三种,因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。


1.1、通过反射获取构造方法并使用

1、获取构造方法:

2、获取无参构造方法并使用

package cn.ref;

import java.lang.reflect.Constructor;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {

        //获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //获取单个构造方法
        Constructor con = c.getConstructor();//返回的是构造方法对象
        
        //通过获取的构造方法创建一个新实例
        Object obj = con.newInstance();
        System.out.println(obj);
        Person p = (Person)obj;
        p.function();
    }
}


3、获取带参构造方法并使用
package cn.ref;

import java.lang.reflect.Constructor;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        //获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //获取带参构造方法
        Constructor con = c.getConstructor(String.class,int.class,String.class);//返回的是构造方法对象
        
        //通过获取的构造方法创建一个新实例
        Object obj = con.newInstance("张三",20,"男");
        System.out.println(obj);
        Person p = (Person)obj;
        System.out.println(p.getName());
    }
}


4、获取私有构造方法并使用
package cn.ref;

import java.lang.reflect.Constructor;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        // 获取私有构造方法
        Constructor con = c.getDeclaredConstructor(String.class);// 返回的是构造方法对象
        //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
        con.setAccessible(true);//设置为true才能访问私有,否则报java.lang.IllegalAccessException
        // 通过获取的构造方法创建一个新实例
        Object obj = con.newInstance("张三");
        System.out.println(obj);
        Person p = (Person) obj;
        System.out.println(p.getName());
    }
}

1.2、通过反射获取成员变量并使用

1、获取成员变量

2、获取公共成员变量并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取成员变量
        Field f = c.getField("sex");
        //赋值
        f.set(obj, "女");
        
        System.out.println(obj);
        Person p = (Person) obj;
        System.out.println(p.getSex());
    }
}


3、获取私有成员变量并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取成员变量
        Field f = c.getDeclaredField("name");
        f.setAccessible(true);
        //赋值
        f.set(obj, "张三");
        
        System.out.println(obj);
        Person p = (Person) obj;
        System.out.println(p.getName());
    }
}


1.3、通过反射获取成员方法并使用

1、获取成员方法

2、获取无参无返回值成员方法并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        //通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取无参成员方法
        Method m = c.getMethod("function");
        //调用方法
        m.invoke(obj);
    }
}

3、获取带参带返回值成员方法并使用
package cn.ref;

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

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        // 通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取带参成员方法
        Method m = c.getMethod("function",String.class,int.class);
        // 调用方法
        Object o = m.invoke(obj,"hello",20);
        System.out.println(o);
    }
}


4、获取私有成员方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
    public static void main(String[] args) throws Exception {   
        // 获取字节码对象
        Class c = Class.forName("cn.ref.Person");
        // 通过构造方法创建一个实例
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        // 获取私有成员方法
        Method m = c.getDeclaredMethod("show");
        m.setAccessible(true);
        // 调用方法
        m.invoke(obj);
    }
}







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2