反射

2018-10-20  本文已影响0人  咔狼

概念

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

Class类

反射的使用

获取Class对象

  1. Object里面提供的方法getClass()
  2. 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
  3. 通过Class类的静态方法forName(String className)(常用)
    Class class1 = Class.forName(className);// 从path内查找class加载,不能指定路径
  4. 通过ClassLoader获取(常用)

通过反射获取构造方法

getConstructor(Class<?>... parameterTypes)
返回一个Constructor对象,它反映此Class对象所表示的类的指定公共构造方法
getConstructors()
返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公共构造方法

通过反射获取成员变量

getField(String name)
返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段
getFields()
返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段

通过反射获取成员方法

getMethod(String name, Class<?>... parameterTypes)
返回一个Method对象,它反映此Class对象所表示的类或接口的指定公共成员方法
getMethods()
返回一个包含某些Method对象的数组,这些对象反映此Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共member方法

拓展实例

public class FileClassLoader extends ClassLoader {

    private File classFile;

    public FileClassLoader(File classFile) {
        super();
        this.classFile = classFile;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            byte[] classData = loadClassData();
            return defineClass(name, classData, 0, classData.length);// 通过defineClass方法将类的字节加载为类
        } catch (IOException e) {
            throw new ClassNotFoundException();// IO异常则为类找不到
        }
    }

    /**
     * 从文件读取类字节
     *
     * @return 类文件的字节数组
     * @throws IOException
     */
    private byte[] loadClassData() throws IOException {
        final int SIZE = 1024;
        byte[] bytes;

        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(classFile))) {
            ByteArrayOutputStream outWriter = new ByteArrayOutputStream();
            byte[] buf = new byte[SIZE];
            int len;
            while ((len = bis.read(buf)) != -1) {
                outWriter.write(buf, 0, len);
            }
            outWriter.flush();
            bytes = outWriter.toByteArray();
        }

        return bytes;
    }
}

接口(被调用的类必须实现这个接口)

package reflect;

public interface Access {
    public <T> void method1(T parameter1);
    public <T> void method2(T parameter1, T parameter2);
}

调用方法

FileClassLoader fileClassLoader = new FileClassLoader(new File("I:\\JAVA_Project\\Test.class"));// 文件名可自定义
Class<?> acsClass = fileClassLoader.loadClass("reflect.Test");// 包名
Access acs = (Access) acsClass.newInstance();// 被调用class必须实现Access接口
acs.method1("测试打印");// 调用方法
上一篇 下一篇

猜你喜欢

热点阅读