反射是允许程序运行时通过Reflection的API获取到类的全部信息,并能操作对象的属性及方法的机制,在框架和设计模式中大量使用;
核心:Class对象,一个类只能有一个Class对象,它包含了类的完整结构信息
可以通过外部文件配置,在不修改源码的情况下来控制程序,符合设计模式中的opc原则,即开闭原则,不修改代码扩展功能
1.通过javac命令将.java文件编译成.class文件
2.运行.class文件,将会执行类加载,分为三个阶段:加载、连接、初始化,其中连接又分为了验证、准备、解析
加载:将类的class文件读入内存,并为之创建一个java.lang.Class对象,此过程由类加载器完成
连接:将类的二进制数据合并到JRE中
初始化:
1)、到初始化阶段,才真正开始执行类中定义的Java程序代码,此阶段是执行()方法的过程
2)、()方法是由编译器按语句在源文件中出现的顺序,依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并进行合并
3)、虚拟机会保证一个类的()方法在多线程环境中被正确的加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的()方法,其他线程都需要阻塞等待,直到活动线程执行()方法完毕
3.类加载后Class对象和类的字节码二进制数据存储在方法区中,而创建的对象实例存储在堆中
1.Class.forName(String name);
2.类名.class
3.对象名.getClass();
4.对象.getClass().getClassLoader().loadClass(String name);
基本数据类型.class获得Class对象
包装数据类型.TYPE获得Class对象,包装数据类型对应的基本数据类型的Class对象实际上和包装数据类型的Class对象是一个Class
简单的反射实例代码:
/** * @author Colt_filly * @version 1.8 */ public class Class01 { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.atguigu.reflection.Student"); Object o = clazz.newInstance(); //获取全类名 System.out.println(clazz.getName()); //获取简单类名 System.out.println(clazz.getSimpleName()); //获取public修饰的属性,包含本类以及父类的 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println(field.get(o)); } //获得本类中所有的属性 Field[] declaredFields = clazz.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField.get(o)); } //获取public修饰的方法,包含本类以及父类的 Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println(method.getName()); } //获取本类中所有的方法 Method[] declaredMethods = clazz.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod.getName()); } //获取public修饰的构造器 Constructor<?>[] constructors = clazz.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor.getName()); } //获取本类中所有的构造器 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); for (Constructor<?> declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor.getName()); } //以Package返回包信息 System.out.println(clazz.getPackage()); //以Class返回父类信息 Class<?> superclass = clazz.getSuperclass(); System.out.println(superclass); //以Class[]返回接口信息 Class<?>[] interfaces = clazz.getInterfaces(); for (Class<?> anInterface : interfaces) { System.out.println(anInterface); } //以Annotation[]返回注解信息 Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation.annotationType().getName()); } } }