反射(Relfect)

反射可以在程序运行时发现并使用对象的类型信息。
反射使我们摆脱了只能在编译时执行面向类型操作的限制,并且让我们能够编写一些非常强大且灵活的程序。
程序中的每个类都有对应的唯一一个Class对象。也就是说,每次编写并编译一个新类时,都会生成一个Class对象(并被相应地存储在同名的 .class文件中)。
事实上,Class对象被用来创建类的所有“常规”对象。
类在首次使用时才会被动态加载到JVM中。当程序第一次引用该类的静态成员时,就会触发这个类的加载。
构造器是类的一个静态方法,尽管没有明确使用static关键字。因此,使用new操作符创建类的新对象也算作对该类静态成员的引用,构造器的初次使用会导致该类的加载。

Class类是描述类的类(类是用来描述一系列拥有共同属性的对象的)

获取Class实例的三种方式

通过类名称.class来获取

Class<?> cls1 = Person.class;

        Class<?> cls2 = int.class;//基本数据类型也能.class
        Class<?> cls3 = void.class;//修饰符也可以.class
        Class<?> cls4 = int[].class;//甚至数组也可以.class

通过对象.getClass()方法来获取

getClass是Object类中的方法,所以任何对象都有getClass方法

Person p1 = new Person();
        Class<?> cls6 = p1.getClass();
        Class<?> cls7 = new int[5].getClass();

通过类的全限定名来获取(全限定名:包名+类名)

Class<?> cls8 = Class.forName("cn.tinsur.lianxi.st6.Person");

需要注意的是,同一个类,不管用什么方法获取,都是一样的,也就是存在如下关系:

IO.println(cls1 == cls7);//true
IO.println(cls6 == cls8);//true

列举常用的一些方法

1.打印类的全限定名

cls1.getName();//cn.tinsur.lianxi.st6.Person
cls1.getSimpleName();//Person

2.获取父类

cls1.getSuperclass();//返回父类类型的Class对象
        //打印父类名称
 IO.println(cls1.getSuperclass().getName());
 IO.println(Student.class.getSuperclass().getName());

3.获取接口

Class<?>[] itfs = cls1.getInterfaces();//返回值是一个数组
IO.println(itfs.length);//1   即只有一个接口
IO.println(itfs[0].getName());//java.io.Serializable

仅演示部分方法

Field(字段)

在反射中,Field是描述字段的类。

例如可以通过以下方式获取上述Person类中的字段:

Field[] fields = cls1.getDeclaredFields();
        IO.println(fields.length);
        for (int i = 0; i < fields.length; i++) {
            //修饰符
            IO.print(Modifier.toString(fields[i].getModifiers()));
            IO.print("  ");
            //字段类型
            IO.print(fields[i].getType().getSimpleName());//getTyoe获取字段类型,返回一个Class对象,getName获取字段类型名称
            //字段名称
            IO.print("  ");
            IO.println(fields[i].getName());

        }

和字段相关的操作

Field nameField = cls1.getDeclaredField("name");
        Person p2 = new Person();

        //通过反射的方式给字段赋值
        nameField.setAccessible(true);//强制将字段改为公有的
        nameField.set(p2,"张三");
        IO.println(p2.getName());
        //通过反射的方式从字段取值
        IO.println(nameField.get(p2));

 

THE END
文章版权归Tinsur.cn所有,不允许任何形式的转载
点赞0 分享