Java的反射

1.Java的反射不同于我们平时的new对象。反射只有在运行时才知道要操作的类是什么,从而在运行时获取类的有关信息,包括构造函数,属性,和函数,并调用对应的函数。

Person类

public class Person {

    private int age;

    private String name;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.我们先体验下什么是反射^_^。。。。我们为上面的Person类创建对象,并调用函数。

        Person person = new Person();
        person.setName("zhangsan");
        person.setAge(25);

        System.out.println(person.getName() + ":" + person.getAge());

        Class clazz = Class.forName("Person");

        Constructor constructor = clazz.getConstructor();

        Object object = constructor.newInstance();

        Method method = clazz.getMethod("setName", String.class);

        Method method1 = clazz.getMethod("setAge", int.class);

        method.invoke(object,"lisi");

        method1.invoke(object,36);

        Method method2 = clazz.getMethod("getName");

        Method method3 = clazz.getMethod("getAge");

        System.out.println(method2.invoke(object) + ":" + method3.invoke(object));

运行结果

zhangsan:25
lisi:36

从上面的代码执行结果可以看出,结果其实都是一样的。第一段代码在未运行时便已确定Person类,所以new出对象。第二种方式,在运行时才通过字符串得知自己运行的类是“Person”。

然后反射调用setName和setAge函数并传递"lisi"和36,最后使用反射调用getName函数,输出其价格。

3.获取反射中Class对象的三种方式

一个类在JVM中只会有一个Class实例。

        //通过对象调用getClass()函数来获取
        Person person = new Person();
        Class clazz = person.getClass();

        //通过Class对象的 forName()静态函数获取
        Class clazz2 = Class.forName("Person");

        //类名.class,每个类都有一个隐含的静态成员变量class
        Class clazz3 = Person.class;

        System.out.println(clazz == clazz2 );

        System.out.println(clazz == clazz3);

        System.out.println(clazz2 == clazz3);

运行结果

true
true
true

4.通过反射创建类对象有两种方式

第一种方式

     Person person = new Person();
     Class clazz = person.getClass();
   //通过Class对的newInstance函数
     Object object = clazz.newInstance();

第二种方式

       Class clazz2 = Class.forName("Person");

       Constructor constructor = clazz2.getConstructor();
       //通过Constructor对象创建类对象可以选择特定的构造函数
       Object object1 = constructor.newInstance();

5.通过反射获取类属性,函数,构造器

       Class clazz = Class.forName("Person");
        //输出类名称
        System.out.println("我是加载的类名" + clazz.getName());

        //获取类的public类型的属性,因为我们都是private私有的。不会输出
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println("我是公有类的名称" + field.getName());
        }

        //获取类的所有属性,包括私有
        Field[] fields1 = clazz.getDeclaredFields();
        for (Field field : fields1) {
            System.out.println("所有类的属性名称:" + field.getName());
        }

        //获取类的public类型的函数。这里包括object类的一些函数
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println("所有函数名称:" + method.getName());
        }

        Method[] methods1 = clazz.getDeclaredMethods();
        for (Method method : methods1) {
            System.out.println("Person类的所有函数" + method.getName());
        }
        
        

6.反射机制并无神奇之处,与new对象之间的区别在与

编译器在编译时打开和检查.class文件

反射,运行时打开和检查.class文件

 

posted @ 2019-01-11 10:45  一剑天门  阅读(176)  评论(0编辑  收藏  举报