反射的笔记

1.反射基本概念:

01.定义:

反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性!

02.作用:

001.在运行期间获取类的修饰符,包名,类名,实现的接口,继承的父类。

002.在运行期间获取类的所有属性名,修饰符,属性类型。

003.在运行期间获取所有方法,方法的返回值类型,方法名,方法参数数量,方法参数类型。

004.在运行期间加载类的方法。

03.java反射API常用的类

001.java.lang.Class

002.java.lang.reflect.Method

003.java.lang.Constructor

004.java.lang.Filed

005.java.lang.Modifier

2.例子

01.使用java反射获取类的信息

001.父类代码

package cn.pb.bean;

/**
 * 父类
 * 
 * @author Administrator
 * 
 */
public class FatherTest {
    private String teststr = "测试用";

    public String getTeststr() {
        return teststr;
    }

    public void setTeststr(String teststr) {
        this.teststr = teststr;
    }

}

002.子类代码

package cn.pb.bean;

/**
 * 测试类 人类  继承了父类
 */
import java.io.Serializable;

public class Person extends FatherTest implements Serializable {
    private int id;
    private String name;
    private String address;
    private String message;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Person() {
        super();

    }

    public Person(int id, String name, String address, String message) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.message = message;
    }

}

003.测试类代码:

package cn.pb.test;


/**
 * 测试类 通过反射获取类的信息
 * 
 * @author Administrator
 * 
 */
public class GetClassInfo {
    public void test(String className) throws Exception {
        // 获取Person类对象 传递的className为类的全类名
        Class clazz = Class.forName(className);

        // 获取类在的包名 clazz.getSimpleName():获取类名
        Package pkg = clazz.getPackage();
        System.out.println(clazz.getSimpleName() + "定义在" + pkg.getName()
                + "包中!");
        System.out.println("*********************");

        // 获取此对象所表示的实体(类,接口,基本类型或者void)的超类Class
        // 如果此对象是一个Object类,一个接口,一个基本类型或void,它的超类返回Null
        // 如果此对象是一个数组类,返回表示Object类的Class对象
        Class superClass = clazz.getSuperclass();
        System.out.println(clazz.getSimpleName() + "的超类是"
                + superClass.getName());
        System.out.println("*********************");

        // 获取Person类所实现的接口
        // 如果Person类没有实现任何接口,返回一个长度为0的数组
        // 如果Person类是一个基本类型或者是void,那么也返回一个长度为0的数组
        Class[] interfaces = clazz.getInterfaces();
        System.out.println("所实现的接口有:");
        for (Class c : interfaces) {
            System.out.println(c.getName());
        }
        System.out.println("******************");
    }

    public static void main(String[] args) throws Exception {
        GetClassInfo getClassInfo = new GetClassInfo();
        getClassInfo.test("cn.pb.bean.Person");
    }

}

02.使用java反射获取类的构造函数的参数列表,并通过构造函数实例化类

001.父类代码

package cn.pb.bean;

/**
 * 父类
 * 
 * @author Administrator
 * 
 */
public class FatherTest {
    private String teststr = "测试用";

    public String getTeststr() {
        return teststr;
    }

    public void setTeststr(String teststr) {
        this.teststr = teststr;
    }

}

002.子类代码

package cn.pb.bean;

/**
 * 测试类 人类  继承了父类
 */
import java.io.Serializable;

public class Person extends FatherTest implements Serializable {
    private int id;
    private String name;
    private String address;
    private String message;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Person() {
        super();
        System.out.println("通过无参构造实例化Person对象");
    }

    public Person(int id, String name, String address, String message) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.message = message;
        System.out.println("通过有参构造实例化Person对象");
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", address=" + address
                + ", message=" + message + "]";
    }

}

003.测试代码

package cn.pb.test;

import java.lang.reflect.Constructor;

/**
 * 使用java反射获取类的构造函数的参数列表,并通过构造函数实例化类
 * 
 * @author Administrator
 * 
 */
public class GetClassConstructorInfo {

    /**
     * 通过反射实例化类的对象
     * 
     * @throws Exception
     */
    public void test1() throws Exception {
        // 参数calssName,为类的全类名
        Class clazz = Class.forName("cn.pb.bean.Person");
        // 通过clazz.newInstance()方法,获取类的实例
        Object obj = clazz.newInstance();

        System.out.println("通过反射实例化的对象:" + obj);
    }

    /**
     * 通过反射获取类的构造函数
     * 
     * @throws Exception
     */
    public void test2() throws Exception {
        // 参数calssName,为类的全类名
        Class clazz = Class.forName("cn.pb.bean.Person");
        // 获取类的构造函数,返回类的所有公共的构造函数
        Constructor[] constructors = clazz.getConstructors();
        System.out.println(clazz.getSimpleName() + "类的公共的构造函数以及构造函数的参数列表类型:");
        for (Constructor constructor : constructors) {
            System.out.println("构造函数的名称为:" + constructor.getName());
            // 获取构造函数的所有参数
            Class[] params = constructor.getParameterTypes();
            if (params.length == 0) {
                System.out.println("此构造函数没有参数!");
            } else {
                System.out.println("该构造函数的参数列表为:【");
                for (int i = 0; i < params.length; i++) {
                    if (i != 0) {
                        System.out.println(",");
                    }
                    System.out.println(params[i].getName());
                }
                System.out.println("");
            }
        }

        // 获取无参构造,如果参数为空,则获取无参构造
        Constructor constructor = clazz.getConstructor();
        // 通过无参构造方法获取类的实例
        Object obj = constructor.newInstance();
        System.out.println("通过无参构造实例化的对象为:" + obj);

        /**
         * 获取有参构造 这个方法只能获得公共的有参构造 想要获取私有的构造方法 可以使用
         * clazz.getDeclaredConstructor(int.class, String.class, String.class,
         * String.class);方法
         */

        Constructor constructor2 = clazz.getConstructor(int.class,
                String.class, String.class, String.class);

        Object obj2 = constructor2.newInstance(12, "xiix", "hah", "wawa");

        System.out.println("通过有参构造实例化的 对象为:" + obj2);
    }

    public static void main(String[] args) throws Exception {
        GetClassConstructorInfo test = new GetClassConstructorInfo();
        // test.test1();
        test.test2();
    }
}

 03.使用java反射获取类的所有方法的信息,并调用类的setter方法进行属性的赋值

001.父类代码

package cn.pb.bean;

/**
 * 父类
 * 
 * @author Administrator
 * 
 */
public class FatherTest {
    private String teststr = "测试用";

    public String getTeststr() {
        return teststr;
    }

    public void setTeststr(String teststr) {
        this.teststr = teststr;
    }

}

002.子类代码

package cn.pb.bean;

/**
 * 测试类 人类  继承了父类
 */
import java.io.Serializable;

public class Person extends FatherTest implements Serializable {
    private int id;
    private String name;
    private String address;
    private String message;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Person() {
        super();
        System.out.println("通过无参构造实例化Person对象");
    }

    public Person(int id, String name, String address, String message) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.message = message;
        System.out.println("通过有参构造实例化Person对象");
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", address=" + address
                + ", message=" + message + "]";
    }

}

003.测试代码

package cn.pb.test;

/**
 * 使用java反射获取类的所有方法的信息,并调用类的setter方法进行属性的赋值
 */
import java.lang.reflect.Method;

public class GetClassMethodsInfo {

    /**
     * 调用类的setter方法进行属性的赋值
     * 
     * @param className
     *            类的全类名
     * @param propName
     *            属性名
     * @param propType
     *            属性类型
     * @param propValue
     *            属性值
     * @throws Exception
     */
    public void invokeSetter(String className, String propName,
            String propType, Object propValue) throws Exception {

        // 通过反射获取类的实例
        Class clazz = Class.forName(className);
        Object obj = clazz.newInstance();
        // 将传过来的属性名 转换成set方法
        String methodName = "set" + propName.substring(0, 1).toUpperCase()
                + propName.substring(1);
        // 根据set方法名和参数列表获取set方法
        Method method = clazz.getDeclaredMethod(methodName,
                Class.forName(propType));

        // 如果需要可以设置setAccessible方法,设置为可以访问
        // method.setAccessible(true);
        // 调用方法并传参 参数为:方法所属的对象和方法的参数
        method.invoke(obj, propValue);//

        System.out.println("通过set方法给类的属性赋值:" + obj);
    }

    /**
     * 使用java反射获取类的所有方法的信息
     */
    public void showMethods() throws Exception {
        Method[] methods;

        // 获取Person类中的所有的方法,不包括继承的类的方法
        // 如果该类或接口没有生命任何方法,或者此Class 对象表示一个基本数据类型,一个数组类或void
        // 那么返回一个长度为0的数组
        methods = Class.forName("cn.pb.bean.Person").getDeclaredMethods();

        System.out.println("******展示方法信息********");
        for (Method method : methods) {
            System.out.println("方法名:" + method.getName());
            System.out.println("方法返回值类型:" + method.getReturnType().getName());

            // 获取方法的参数列表
            Class[] params = method.getParameterTypes();
            if (params.length == 0) {
                System.out.println("该方法没有参数!");
            } else {
                System.out.println("该方法的参数列表为:【");
                for (int i = 0; i < params.length; i++) {
                    if (i != 0) {
                        System.out.println(",");
                    }
                    System.out.println(params[i].getName());
                }
                System.out.println("");
            }

            // 获取方法所属的类或接口的class对象
            Class declaringClass = method.getDeclaringClass();
            System.out.println("方法声明在:" + declaringClass.getName() + "中!");

            // 获取方法抛出的异常的类型,即throws子句中声明的异常
            Class[] exceptions = method.getExceptionTypes();
            if (exceptions.length > 0) {
                System.out.println("该方法抛出的异常有:【");
                for (int i = 0; i < exceptions.length; i++) {
                    if (i != 0) {
                        System.out.println(",");
                    }
                    System.out.println(exceptions[i].getName());
                }
                System.out.println("");
            }

            System.out.println("***********************");

        }
    }

    public static void main(String[] args) throws Exception {
        GetClassMethodsInfo test = new GetClassMethodsInfo();
        // test.invokeSetter("cn.pb.bean.Person", "name", "java.lang.String",
        // "zhangsan");
        test.showMethods();
    }
}

 04.使用java反射获取类的所有属性的名称和类型,并为其中一个属性赋值

001.父类代码

package cn.pb.bean;

/**
 * 父类
 * 
 * @author Administrator
 * 
 */
public class FatherTest {
    private String teststr = "测试用";

    public String getTeststr() {
        return teststr;
    }

    public void setTeststr(String teststr) {
        this.teststr = teststr;
    }

}

002.子类代码

package cn.pb.bean;

/**
 * 测试类 人类  继承了父类
 */
import java.io.Serializable;

public class Person extends FatherTest implements Serializable {
    private int id;
    private String name;
    private String address;
    private String message;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Person() {
        super();
        System.out.println("通过无参构造实例化Person对象");
    }

    public Person(int id, String name, String address, String message) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.message = message;
        System.out.println("通过有参构造实例化Person对象");
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", address=" + address
                + ", message=" + message + "]";
    }

}

003.测试代码

package cn.pb.test;

import java.lang.reflect.Field;

/**
 * 使用java反射获取类的所有属性的名称和类型,并为其中一个属性赋值
 * 
 * @author Administrator
 * 
 */
public class GetClassFieldsInfo {
    /**
     * 使用java反射获取类的所有属性的名称和类型
     * 
     * @throws Exception
     */
    public void showFields() throws Exception {
        Field[] fields;

        // 获取Person类中的所有字段,但不包括继承的字段
        // 如果该类或接口不声明任何字段,或者此Class 对象表示一个基本数据类型,一个数组类或void
        // 那么返回一个长度为0的数组
        fields = Class.forName("cn.pb.bean.Person").getDeclaredFields();

        // 遍历
        System.out.println("**********字段展示***********");
        for (Field field : fields) {
            System.out.println("字段名:" + field.getName());
            System.out.println("字段类型:" + field.getType().getName());
            System.out.println("********************");
        }
    }

    /**
     * 通过使用反射操作person类的字段 使用java反射获取类的对象的实例,并为其中一个属性赋值
     */
    public void accessField() throws Exception {
        // 通过反射加载一个Person实例
        Class clazz = Class.forName("cn.pb.bean.Person");
        Object obj = clazz.newInstance();

        // 通过getDeclaredField("address")方法 获取类的指定字段
        Field address = clazz.getDeclaredField("address");
        // address字段为private,这里已经超出其访问范围,不能直接访问
        // 通过setAccessable方法,设定为可以访问
        address.setAccessible(true);

        System.out.println("赋值前的address:" + address.get(obj));
        // 为address属性赋值
        address.set(obj, "北大青鸟");
        System.out.println("赋值之后的address:" + address.get(obj));
    }

    public static void main(String[] args) throws Exception {
        GetClassFieldsInfo test = new GetClassFieldsInfo();
        test.showFields();
        test.accessField();
    }

}
原文地址:https://www.cnblogs.com/lyb0103/p/7636189.html