java反射学习笔记

87 阅读3分钟

一点反射内容:

反射

反射原理图

public class Reflection01 {
    public static void main(String[] args) throws Exception {
        //1使用Propertis类 可以读写配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\re.properties"));

        String classfullpath = properties.get("classfullpath").toString();
        String methodName = properties.get("method").toString();

        //2. 使用反射机制解决
//(1) 加载类, 返回 Class 类型的对象 cls
        Class cls = Class.forName(classfullpath);
//(2) 通过 cls 得到你加载的类 com.hspedu.Cat 的对象实例
        Object o = cls.newInstance();
        System.out.println("o 的运行类型=" + o.getClass()); //运行类型
//(3) 通过 cls 得到你加载的类 com.hspedu.Cat 的 methodName"hi" 的方法对象
// 即:在反射中,可以把方法视为对象(万物皆对象)
        Method method1 = cls.getMethod(methodName);
//(4) 通过 method1 调用方法: 即通过方法对象来实现调用方法
        System.out.println("=============================");
        method1.invoke(o); //传统方法 对象.方法() , 反射机制 方法.invoke(对象)

        //java.lang.reflect.Field: 代表类的成员变量, Field 对象表示某个类的成员变量
//得到 name 字段
//getField 不能得到私有的属性
        Field nameField = cls.getField("name");

        //// 传统写法 对象.成员变量 , 反射 : 成员变量对象.get(对象)!!!
        System.out.println(nameField.get(0));

        ////java.lang.reflect.Constructor: 代表类的构造方法, Constructor 对象表示构造器
        //()中可以指定构造器参数类型, 返回无参构造器
        Constructor constructor = cls.getConstructor();
        System.out.println(constructor);//没有形参的构造器
//通过反射获取属性
        Constructor constructor1 = cls.getConstructor(String.class);
        System.out.println(constructor1);//有参构造器
    }
}
public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        m1();
        m2();
        m3();
    }

    //传统
    public static void m1() {
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统方法调用hi" + (end - start));
    }

    //反射机制调用方法
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.hspedu.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反射调用方法 反射 : 成员变量对象.invoke(对象)
        }
        long end = System.currentTimeMillis();
        System.out.println(+(end - start));
    }

    //反射调用优化+关闭访问机制
    public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.hspedu.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        hi.setAccessible(true);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反射调用方法 反射 : 成员变量对象.get(对象)!!!
        }
        long end = System.currentTimeMillis();
        System.out.println(+(end - start));
    }
}
public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        String classAllPath = "com.hspedu.reflecton.question.Car";
        //获取Car类对应的class对象
        Class<?> aClass = Class.forName(classAllPath);

        //显示aClass对象
        System.out.println(aClass);
//输出运行类型
        System.out.println(aClass.getClass());
//得到包名

        System.out.println(aClass.getPackage().getName());
        //通过aClass创建对象实例
        Car car = (Car)aClass.newInstance();

        System.out.println(car);

        //通过反射得到属性brand
        Field brand1 = aClass.getField("brand");
        System.out.println(brand1.get(car));//成员属性.get(对象)

        //通过反射给属性赋值
        brand1.set(car,"奔驰");
        System.out.println(brand1.get(car));//成员属性.get(对象)
        //反射就是在不修改源码的条件下修i该属性

        //希望可以得到所有的属性
        Field[] fields = aClass.getFields();
        for (Field f:fields ) {
            System.out.println(f.getName());
        }
    }
}
public class GetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        //通过读取配置文件读取
        //方法一 在框架用的最多
        String classAllPath = "com.hspedu.reflecton.question.Car";
        Class<?> aClass = Class.forName(classAllPath);
        System.out.println(aClass);

        //方法二
        //类名.class  应用于参数传递
        Class cls1 = Car.class;
        System.out.println(cls1);

        //应用场景 有对象实例
        Car car = new Car();
        Class<? extends Car> cls3 = car.getClass();
        System.out.println(cls3);

        //4. 通过类加载器【4 种】来获取到类的 Class 对象
//(1)先得到类加载器 car
        ClassLoader classLoader = car.getClass().getClassLoader();
        //(2)通过类加载器得到 Class 对象
        Class<?> cls4 = classLoader.loadClass(classAllPath);
        System.out.println(cls4);


        //cls1 , cls2 , cls3 , cls4 其实是同一个对象
        System.out.println(aClass.hashCode());
        System.out.println(cls1.hashCode());
        System.out.println(cls3);
        System.out.println(cls4.hashCode());
        System.out.println(cls4);

//        基本数据(int, char,boolean,float,double,byte,long,short) 按如下方式得到 Class 类对象
        Class<Integer> integerClass = int.class;
        Class<Character>  characterClass = char.class;
        Class<Boolean> booleanClass = boolean.class;
        System.out.println(integerClass);

        //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到 Class 类对象
        Class<Integer> typel = Integer.TYPE;
        Class<Character> type2 = Character.TYPE;
        System.out.println(typel);

        System.out.println(integerClass.hashCode());
        System.out.println(typel.hashCode());
    }
}