java 反射的概念: java 的反射机制是指在运行状态下, 对于一个类来说, 可以得到这个类的所有方法和属性. 对于一个对象来说, 可以调用这个对象的人和方法和属性. 反射机制首先会拿到该类的字节码文件 (Class 文件), 然后反向获取这个类的所有信息.(注意: 一个类型的类在运行中, 只产生一个 class 文件)
既然反射的前置条件是获取 class 类, 所以不得不提出获取 class 的方法.
获取 class 的几种方式:
- (1)Persion p=new Persion();
- Class c=p.getClass();
该方法不推荐使用, 因为已经有了 persion 对象, 反射多此一举.
(2)Class c=Persion.class;
任意的类都是继承 object 类, 任何类也都有. class 属性, 说明 object 里面有一个 class 用来获取类的信息, 但是该方法需要倒入包, 依赖强.
(3)Class c =Class.forName("com.xxxx.xxxx")
推荐第三种, 无序导包, 效率较高.
以上三种方法获得的 c 对象都是同一个对象, 因为类在运行的过程中, 只产生一个 class 文件.
反射重要的类和方法
(1)Class 类
getName(): 获得类的完整名字.
getFields(): 获得类的 public 类型的属性.
getDeclaredFields(): 获得类的所有属性. 包括 private 声明的和继承类
getMethods(): 获得类的 public 类型的方法.
getDeclaredMethods(): 获得类的所有方法. 包括 private 声明的和继承类
getMethod(String name, Class[] parameterTypes): 获得类的特定方法, name 参数指定方法的名字, parameterTypes 参数指定方法的参数类型.
getConstructors(): 获得类的 public 类型的构造方法.
getConstructor(Class[] parameterTypes): 获得类的特定构造方法, parameterTypes 参数指定构造方法的参数类型.
newInstance(): 通过类的不带参数的构造方法创建这个类的一个对象.
- boolean isPrimitive = class1.isPrimitive();// 判断是否是基础类型
- boolean isArray = class1.isArray();// 判断是否是集合类
- boolean isAnnotation = class1.isAnnotation();// 判断是否是注解类
- boolean isInterface = class1.isInterface();// 判断是否是接口类
- boolean isEnum = class1.isEnum();// 判断是否是枚举类
- boolean isAnonymousClass = class1.isAnonymousClass();// 判断是否是匿名内部类
- boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);// 判断是否被某个注解类修饰
- String className = class1.getName();// 获取 class 名字 包含包名路径
- Package aPackage = class1.getPackage();// 获取 class 的包信息
- String simpleName = class1.getSimpleName();// 获取 class 类名
- int modifiers = class1.getModifiers();// 获取 class 访问权限
- Class<?>[] declaredClasses = class1.getDeclaredClasses();// 内部类
- Class<?> declaringClass = class1.getDeclaringClass();// 外部类
(2)Field 类 (一般于 Class 类连用)
- Class c =Class.forName("XXXX");
- Field fields=c.getDeclaredFields("fieldName");
- fields.setAccessible(true);// 设置私有变量可访问
- Object obj=c.newInstance();
- fields.set(obj,"xxx")// 设置变量的值
- (3)Method
- Class.forName("com.XXX.XXX." + className).newInstance().getMethod("methodName").invoke(lass.forName("com.XXX.XXX." + className).newInstance())// 调用反射对象的方法
反射的应用场景:
(1) 简单工厂
(2) 代理模式
(3) 一般还和配置文件共同使用
- Class clazz = Class.forName("com.XXX.XXX." + className);//className 为配置文件 className 的值
- Object obj = clazz.newInstance();
- Method method = clazz.getMethod(methodName);//methodName 为配置文件 methodName 的值
- method.invoke(obj);
欢迎大家批评指正, 共同学习, 共同进步.
来源: http://www.bubuko.com/infodetail-2888585.html