反射的笔记

Posted 迷茫王子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射的笔记相关的知识,希望对你有一定的参考价值。

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();
    }
}

 

以上是关于反射的笔记的主要内容,如果未能解决你的问题,请参考以下文章

java 反射代码片段

反射机制入门

OpenGL片段着色器不照亮场景

为啥我的 Ray March 片段着色器反射纹理查找会减慢我的帧速率?

笔记:反射

反射笔记