反射(reflection)

  • 允许在程序执行期间,借助Reflection APi取得任何类的内部信息,并可以直接操作任意对象的内部属性及方法
  • java.lang.Class:代表一个类,java.lang.reflection.*;等等是反射的主要API

关于java.lang.Class的理解

  • 类加载的过程
    1. 程序经过javac.exe命令后,会生成一个或多个字节码文件(.class文件)
    2. 使用java.exe命令对某个字节码文件进行解释运行(将文案加载到内存中,即内存加载)
    3. 加载到内存的类.就是运行时类,就是Class的一个实例
public class Test2 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 方式一: 电泳运行时类的属性class
        Class class1 = Person.class;
        System.out.println(class1);
        // 方式二: 通过运行时类的对象,调用getClass()
        Person person1 = new Person();
        Class class2 = person1.getClass();
        System.out.println(class2);
        // 方式三: 调用Class的静态方法 forName(String classPath)
        Class class3 = Class.forName("com.gcl.exe1.Person");
        System.out.println(class3);
        // 方式四: 使用类加载器 ClasssLoad
        ClassLoader classLoader = Test2.class.getClassLoader();
        Class class4 = classLoader.loadClass("com.gcl.exe1.Person");
        System.out.println(class4);
    }
}

使用反射Load加载properties文件

public class Test3 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        FileInputStream fileInputStream = new FileInputStream("/Users/guochongling/WorkSpace/IDEA/JAVA_SE/day11/src/com/gcl/exe1/jdbc.properties");
        properties.load(fileInputStream);

        String name = properties.getProperty("name");
        String age = properties.getProperty("age");
        System.out.println(name);
        System.out.println(age);

        // 反射
        ClassLoader classLoader = Test3.class.getClassLoader();
        // 路径默认在src下
        InputStream inputStream = classLoader.getResourceAsStream("com/gcl/exe1/jdbc.properties");
        properties.load(inputStream);

        String name2 = properties.getProperty("name");
        String age2 = properties.getProperty("age");
        System.out.println(name2);
        System.out.println(age2);

    }
}

通过反射创建对应的运行时类的对象

public class Test1 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1. newInstance() 创建对应的运行对象
        Class clazz = String.class;
        Object obj = (String) clazz.newInstance();
        System.out.println(obj.getClass());

        //2. 使用构造器
        Constructor constructor = clazz.getConstructor(String.class);
        Object object = (String)constructor.newInstance("你好");
        System.out.println(object);
    }
}

获取运行时类的属性内部结构

public class Test1 {
    public static void main(String[] args) {
        Class clazz = Person.class;
        // 获取当前运行类及其父类的public属性
        Field[] fields = clazz.getFields();
        for (Field field: fields) {
            System.out.println(field);
        }
        System.out.println("-------------------");
        // 获取当前运行类的所有属性
        Field[] fields1 = clazz.getDeclaredFields();
        for (Field field: fields1) {
            System.out.println(field);
        }

        // 权限修饰符 数据类型 变量名
        Field[] fields2 = clazz.getDeclaredFields();
        for (Field field: fields2) {
            //权限修饰符(返回值为int)
            System.out.println(field.getModifiers());
            System.out.println(Modifier.toString(field.getModifiers()));
            // 数据类型
            System.out.println(field.getType());
            // 变量名
            System.out.println(field.getName());
        }



    }
}

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐