JAVA温习课堂11

49、反射
    Class 是对一个类的描述
        类的属性: Field
        类的方法: Method
        类的构造器:Constrctor
    对象照镜子后可以得到的信息:类的数据成员名、方法和构造器、实现了哪些接口
    对于每个类 JRE都为其保留一个不变的Class类型的对象,一个Class对象包含了特定某个类的有关信息
    Class对象只能由系统建立对象
    一个类在JVM 中只会有一个Class实例
        得到Class 对象
            直接通过 类名.class 的方式得到
            通过对象调用 getClass( )方法获取
            通过全类名的方式获取    用的较多(常用)
    public void testClassMethod() throws Exception{
            Class classTemp = null;
            classTemp = Person.class;

            //利用 Class 对象的 newInstance( )方法来创建Class的对象
            //实际调用的是类的那个无参数的构造器
            //一个类若声明了一个带参数的构造器,也要声明一个无参数的构造器
            String className = "com.classloader.Person";
            Class classTemp1 = Class.forName(className);

            Object obj = classTemp1.newInstance();
            System.out.println(obj);
    }
ClassLoader 类装载器(bootstrap 启动类加载器  user-defined class loader 用户自定义装载器)
    将类装载到JVM中
        Bootstap ClassLoader
    public void testClassLoader() throws Exception{
        // 获取一个系统的类加载器
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        System.out.println(classLoader);

        // 获取系统类加载器的父类加载器
        classLoader = classLoader.getParent();
        System.out.println(classLoader);

        //获取扩展类加载器的父类加载器
        classLoader = classLoader.getParent();
        System.out.println(classLoader);

        //测试当前类使用哪个加载器进行加载
        classLoader = Class.forName("com.classloader.Person").getClassLoader();
        System.out.println(classLoader);

        //测试JDK提供的Object 类由哪个类加载器负责加载
        classLoader = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader);

        //类加载器的一个主要方法
        InputStream in = null;
        in = this.getClass().getClassLoader().getResourceAsStream("test.properties");
        System.out.println(in);     
                //new FileInputStream("test.properties");

        in.close();
    }

    调用getResourceAsStream( )获取类路径下的配置文件

反射(Reflection)

    public void testMethod() throws Exception{
        Class classTemp = Class.forName("com.classloader.Person");;

        // getMethods( )方法 获取加载类中的方法,但是无法获取私有(private)方法
        Method [] methods = classTemp.getMethods();

        for(Method methodStr : methods){
            System.out.println("方法名:" + methodStr.getName());
        }

        // getDeclaredMethods( )方法 获取加载类中的方法,包含private方法,只含有当前类声明的方法
        Method [] methods1 = classTemp.getDeclaredMethods();

        for(Method methodStr : methods1){
            System.out.println("所有方法名:" + methodStr.getName());
        }

        // 获取指定方法
        Method method = classTemp.getDeclaredMethod("play");
        System.out.println(method);

        method = classTemp.getDeclaredMethod("sleep",int.class);
        System.out.println(method);

        method = classTemp.getDeclaredMethod("sleep", int.class,String.class);
        System.out.println(method);

        // 通过Method 对象的invoke( )执行方法
        // public Object invoke(Object obj,Object... args)
        // 参数obj:执行哪个对象的方法
        // 参数args:执行方法时需要传入的参数
        Object obj = classTemp.newInstance(); 
        method.invoke(obj,20,"EngineerZhong");
    }

示例代码:
    public static void main(String[] args) throws ClassNotFoundException{
        //全类名
        String className = "com.reflectiondemo.Student";
        String methodName = "method3";

        Class classTemp = Class.forName(className);

        Object[] objectsTemp = {"EngineerZhong",12};

        Class[] parameterTypes = new Class[objectsTemp.length];

        for(int i = 0 ;i<objectsTemp.length;i++){
            parameterTypes[i] = objectsTemp[i].getClass();          
        }

        Method method = null;
        for( ;classTemp != Object.class;classTemp = classTemp.getSuperclass()){
            try {
                method = classTemp.getDeclaredMethod(methodName, parameterTypes);
            } catch (Exception e) {

            }
        }
        System.out.println(method); 
    }

代码输出:
    private java.lang.Object com.reflectiondemo.Person.method3(java.lang.String,java.lang.Integer)

示例代码:(代码可提取成多个方法,进行调用,此处不在赘述)

    @Test
    public void testField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

        String className = "com.reflectiondemo.Person";
        Class classTemp = Class.forName(className);

        // 获取全部字段
        Field[] fields = classTemp.getDeclaredFields();
        for(Field field : fields){
            System.out.println(field.getName());
        }

        //获取指定名字的Field
        Field fieldTemp = classTemp.getDeclaredField("name");
        System.out.println(fieldTemp.getName());

        //获取指定对象的Field 的值
        Person person = new Person("EngineerZhong", 20);
        Object value = fieldTemp.get(person);
        System.out.println(value);

        // 设置指定对象的Field 的值
        fieldTemp.set(person,"EngineerYe");
        System.out.println(person.getName());

        // 若该字段是私有的,需要调用setAccessible(true) 方法
        fieldTemp = classTemp.getDeclaredField("age");
        fieldTemp.setAccessible(true);
        System.out.println(fieldTemp.get(person));
    }

代码输出:
    name
    age
    name
    EngineerZhong
    EngineerYe
    20

Field 设置 对象属性 实例代码:(代码可提取成多个方法,进行调用,此处不在赘述)
    @Test
    public void testClassField() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
        String className = "com.reflectiondemo.Student";
        String fieldName = "age";

        Object value = 21;

        Object obj = null;

        Class classTemp = Class.forName(className);
        Field field = null;

        for(Class class2 = classTemp;class2 !=Object.class;class2 = class2.getSuperclass()){
            try {
                field = class2.getDeclaredField(fieldName);

            } catch (Exception e) {} 
        }

        obj = classTemp.newInstance();
        field.setAccessible(true);
        field.set(obj, value);

        Student stu = (Student) obj;

        System.out.println("Getter age : " + stu.getAge());
    }

代码输出:
    50
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值