反射的原理与基本应用

一句话概括就是使用反射可以赋予jvm动态编译的能力,否则类的元数据信息只能用静态编译的方式实现,例如热加载,Tomcat的classloader等等都没法支持。
一、Java的编译
1.静态编译:编译时确定类型,源代码到class字节码文件,将类、构造器、方法、属性等信息写入到class字节码文件中
2.动态编译:运行时确定类型,绑定对象。动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。
反射是实现动态编译的基础,实际上指的就是可以在运行时,利用class的字节码文件,通过Reflection APIs创建Class类型的对象,并获取到modifiers(诸如public、static等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。

应用场景:1、tomcat的Servlet;2、Spring的IOC,如何根据xml或者注解创建bean;3、消息发送的序列化与反序列化等等;
抽象的应用场景:一般是在能提供标准的接口,其实也就是能规范方法,但是需要扩展具体实现的时候,可以对外定义方法,然后提供配置文件;例如:Servlet的产生,是需要在web.xml中配置Servlet的全限定名;bean的产生也是。实际上,这里都是提供反射,利用全限定名生成具体的对象,然后由于对象所属的类实现的是我们定义好的接口,那么我们可以执行固定的方法;具体的实现由用户完成。

反射的需要的类:
实现Java反射机制的类都位于java.lang.reflect包中:
1、Class类:代表一个类
2、Field类:代表类的成员变量(类的属性)
3、Method类:代表类的方法
4、Constructor类:代表类的构造方法
5、Array类:提供了动态创建数组,以及访问数组的元素的静态方法

反射的基本操作:
1、创建Class对象:1、类.class;2、对象.getClass();3、Class.forName(“全限定名”);
2、根据Class对象获取constructor(构造器)、method(方法)、field(属性)、annotation(注解);
注意:getDeclaredAnnotations/getDeclaredMethods/getDeclaredConstructors/getDeclaredFields这些方法返回的包括public与非public修饰的数据;另外一种则只有public修饰的数据。
3、获取到反射对象后,可以进行相应的操作;简单示例如下:

import lombok.AllArgsConstructor;
import lombok.Data;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @ Author     :lzz
 * @ Date       :16:12 2019/1/1
 * @ Description:
 * @ Modified By:
 * @ Version:
 */
@Data
@AllArgsConstructor
public class User {

    private String username;
    private String password;

    public User(){

    }

    public String say(String str){
        System.out.println("str is "+str);
        return str;
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        Class clazz = User.class;
        System.out.println("user is "+clazz.newInstance());

        Method method = clazz.getMethod("say",String.class);
        method.invoke(clazz.newInstance(),"111");

        Constructor constructor = clazz.getConstructor();
        Object o = constructor.newInstance();
        System.out.println("o is "+o);

        Method method1 = ReflectionUtils.findMethod(clazz,"say",String.class);
        method1.invoke(clazz.newInstance(),"spring111");
    }
}

其中ReflectionUtils是spring团队开发的反射工具类,相对来说更为完善;无需处理接口、子类、父类、异常等各种情况;

你可能感兴趣的:(Java)