Java中的重要机制---反射

什么是反射?

        反射是java提供的一种机制,这种机制可以动态的获取运行中的程序的任意类的所有属性与方法,以及可以创建该类的对象,调用对象中的属性与方法

反射的作用:获取类的所有属性与方法

为什么使用反射?

        使用反射可以使得程序更加灵活,例如可以编写一套特定的机制用来处理任意的类,例如mybatis框架中的查询结果映射可以通过反射帮助我们创建对象返回映射结果,servlet在web.xml文件中注册servlet时也是通过反射机制创建servlet类的对象,框架都是通过一套特定的机制来处理所有的类,这样可以使得程序变得更加灵活

反射API

Class类

        每个类都会有一个且只有一个对应的Class类对象,Class类对象会在类加载进内存的时候创建,通过Class类的对象就可以拿到对应类的所有信息,这也是反射机制为什么只能在程序运行状态下才能获取类的信息的原因,Class类是反射实现的基础

获取Class类

通过类名获取:

        任何数据类型(包括基本数据类型)都有一个“静态”的class属性

        例: Class class = User.class;

使用Object的Class类对象获取:

        Object类中提供了获取当前类的Class对象的方法getClass()

        例: User user = new User();

        Class class = user.class;

通过Class.forName("全类名")方法获取

        Class类中提供了forName静态方法能根据类的地址加载类并且能获取类的对象

        例: Class class = Class.forName("com.xxx.xxx.User");

Constructor类

Constructor类能够获取到对应类的构造方法的信息

获取Constructor类

        Class类中提供了获取Constructor类对象的方法

        Constructor<T> getConstructor(Class... parameterTypes) ,根据参数获取类中指定的公共的构造方法

Constructor<T> getDeclaredConstructor(Class... parameterTypes),获取指定的构造方法,包括私有的

Constructor[ ] getConstructors()获取所有的公共构造方法

Constructor[ ] getDeclaredConstructors()获取所有的构造方法,包括私有的

Constructor类中的方法

boolean isAccessible(),用于判断构造方法是否是私有的

void setAccessible(boolean b),用于设置构造方法的访问权限

String getName(),返回构造器的方法名,其他的信息也可以通过getXXXX()的形式获取

 //Constructor类,接收class类获取的构造方法
        String classname = "com.yzl.javareflect.Admin";
        Class c = Class.forName(classname);
        Object obj1 = c.newInstance();//newInstance()方法获取创建类的对象,反射创建类对象1
​
        //getConstructor()获取公共的指定构造方法,根据传入参数判断是否有参
        Constructor constructor1 = c.getConstructor();
        Object obj2 = constructor1.newInstance();//构造器类创建类对象反射创建类对象2
​
        Constructor constructor2 = c.getConstructor(int.class,String.class);//获取有参构造方法时需要传入形参的class类作为参数
        constructor2.newInstance();
​
        //getDeclaredConstructor()获取指定的构造方法,包括私有的
        Constructor constructor3 = c.getDeclaredConstructor(int.class,String.class,String.class);
        //isAccessible()方法判断获取的构造方法是否是私有的,setAccessible()方法设置可以访问私有的权限
        if (!constructor3.isAccessible()){
            constructor3.setAccessible(true);
        }
​
        //getDeclaredConstructors()获取所有的构造方法,无论私有还是公共的,返回一个Constructor数组
        Constructor[] constructors = c.getDeclaredConstructors();

创建对象的第三种方式

已经学过的创建对象的方式:new关键字创建,对象的反序列化

反射也可以创建对象,反射中创建对象的两种方式

1.Class类中的newInstance()方法创建实例

2.Constructor类中的newInstance()方法创建实例

Field类

Field类可以获得属性的基本信息、属性的值,也可以对属性进行赋值

获取Field类

Class类中也提供了获取Constructor类对象的方法

Filed geFiled (String name) ,根据属性名获取类中指定的公共属性

Filed getDeclaredFiled (String name),根据属性名获取类中指定的任意属性,包括私有的

Filed [ ] getConstructors(),获取类中所有的公共属性

Filed [ ] getDeclaredConstructors(),获取所有的属性,包括私有的

Field类中的方法

boolean isAccessible(),用于判断属性是否是私有的

void setAccessible(boolean b),用于设置属性的访问权限

Field类中提供了获取Field类的属性的方法以及赋值的方法,但是一般不会直接进行赋值而是通过类中的getter与setter方法获取属性值以及赋值,避免打破属性的封装性

Method类

Method方法用于获取方法的信息,可以执行方法

获取Method类

Method类与Field类,Constructor类非常相似获取的方法几乎一样,Class类中也提供了获取Method类对象的方法

Method geMethod (String name) ,根据方法名获取类中指定的公共方法

Method getDeclaredMethod (String name),根据方法名获取类中指定的任意方法,包括私有的

Method [ ] getMethods(),获取类中所有的公共方法

Method [ ] getDeclaredMethods(),获取所有的方法,包括私有的

Method类中的方法

invoke(对象引用,Object……args),用于执行method当前获取的方法

Method类也提供了访问私有方法的途径,与Field类中的一样

        String classname = "com.yzl.javareflect.Admin";
        Class c = Class.forName(classname);
        Object obj = c.newInstance();
​
        Field[] fields = c.getDeclaredFields();
        for (Field f : fields){
​
        Method m = c.getMethod("set" + f.getName().substring(0,1).toUpperCase()+f.getName().substring(1) ,f.getType());
            m.invoke(obj,"111");//执行方法
​
        }

优缺点

优点:

1.使程序更加灵活,能够已特定的方式处理任意类的信息

2.能够动态的获取类的信息

3.提高代码的复用率,动态代理

缺点:

1.破坏了类的封装性,不安全

2.反射涉及到类的解析,性能比直接调用类要低

猜你喜欢

转载自blog.csdn.net/yzl1293346757/article/details/128019073