美文网首页
【Java梳理】反射

【Java梳理】反射

作者: 田文健 | 来源:发表于2018-05-05 18:05 被阅读0次

    1.反射是什么
    Java中反射的通常描述是,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。这种方法非常有用,他可以动态地创建对象,对一个对象进行获取变量,修改变量,调用方法等操作,而不需要在代码中体现是具体的哪一个类。
    2.反射实例
    我们知道,Java中的类文件是以class文件的形式存在磁盘上的,在程序运行时会被ClassLoader加载进内存去的静态方法区中。Java提供了Class类来表示一个类的信息。
    比如现在有一个类:

    public class Alaska implements Dog {
    
        private Double weight; //体重
    
        @Override
        public void bark() {
            System.out.println("汪,汪!");
        }
    
        public Alaska(){
            weight = 22.0D;
        }
    
        public Double getWeight() {
            return weight;
        }
    }
    

    分别用类和对象的方式来获取 Class 对象(也可以用forName方法。main方法完整的代码在文章末尾):

    public static void main(String... args){
    
            //直接获取
            Class class1 = Alaska.class;
    
            //通过对象获取
            Dog dog = new Alaska();
            Class class2 = dog.getClass();
    
            System.out.println("class1 is " + class1.getName());
            System.out.println("class2 is " + class2.getName());
        }
    

    运行结果:
    class1 is animal.Alaska
    class2 is animal.Alaska
    这里需要说明的是,当用对象方法获取Class的时候,获取的是实际构造这个对象的类。getClass方法是在Object类中定义的,而Object类是所有类的父类。

    接下来用反射的方法类构造对象:

     try {
                //调用无参构造方法
                Object o = class2.newInstance();
                 System.out.println("weight is " + ((Alaska) o).getWeight());
            } catch (Exception e) {
                e.printStackTrace();
            }
    

    输出:
    weight is 22.0

    之后尝试改变weight的值:

    Field field = class2.getDeclaredField("weight");
                field.setAccessible(true);
                field.set(o, 33.0D);
                field.setAccessible(false);
                System.out.println("修改后的 weight 是 " + ((Alaska) o).getWeight());
    

    输出:
    修改后的 weight 是 33.0

    这里需要注意的是使用getDeclaredField方法,可以获取共有或者私有的变量。

    然后是调用类成员方法:

    Method method = class2.getDeclaredMethod("bark");
     method.invoke(o);
    

    输出:
    汪,汪!
    在Java中反射的应用非常广泛。这里只简单介绍反射的操作。
    完整的main方法代码:

    public static void main(String... args){
    
            //直接获取
            Class class1 = Alaska.class;
    
            //通过对象获取
            Dog dog = new Alaska();
            Class class2 = dog.getClass();
    
            System.out.println("class1 is " + class1.getName());
            System.out.println("class2 is " + class2.getName());
    
            try {
                Object o = class2.newInstance();
                System.out.println("weight is " + ((Alaska) o).getWeight());
    
                Field field = class2.getDeclaredField("weight");
                field.setAccessible(true);
                field.set(o, 33.0D);
                field.setAccessible(false);
                System.out.println("修改后的 weight 是 " + ((Alaska) o).getWeight());
    
                Method method = class2.getDeclaredMethod("bark");
                method.invoke(o);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    相关文章

      网友评论

          本文标题:【Java梳理】反射

          本文链接:https://www.haomeiwen.com/subject/ozgwbxtx.html