每日视点!Java反射机制介绍
1.通过反射,我们可以构建实例,得到成员变量的值,得到方法并调用。
(资料图)
还可以获得定义在成员变量、方法、方法参数上的注解。
接下来看代码实现,然后讲原理。
1)构建无参实例:通过反射调用无参构造函数
//1.通过全类名加载字节码对象 Class clazz = Class.forName("com.example.lib.Person"); //2.通过类的字节码拿到定义的构造函数 Constructor constructor = clazz.getConstructor(); //3.通过构造方法创建对象 Object obj = constructor.newInstance();
2)构建有参数实例:
//1.通过全类名加载字节码对象 Class clazz = Class.forName("com.example.lib.Person"); //2.通过类的字节码拿到定义的构造函数 Constructor constructor = clazz.getConstructor(int.class,String.class); //3.通过构造方法创建对象 Object obj = constructor.newInstance(20,"xiaohua");
3)通过反射获取成员变量的值。
//4.通过属性名获取属性 Field field = clazz.getDeclaredField("age"); field.setAccessible(true); //5.调用get方法拿到对象obj属性age的值 Integer age = (Integer) field.get(obj);
4)通过反射调用对象的方法。
//4.通过方法名和参数类型,拿到方法 method = clazz.getMethod("setAge", int.class); //5.调用方法 obj是哪个对象身上的方法。 method.invoke(obj, 21); method = clazz.getMethod("getAge"); method.invoke(obj);
5).通过反射获取静态变量的值。
//1.通过全类名加载字节码对象 Class clazz = Class.forName("com.example.lib.Person"); //2.获取静态属性ID Field field = clazz.getField("ID"); field.setAccessible(true); //3.拿到静态属性ID的值。 // 因为静态变量存在方法区,在对象创建之前,就已经加装到了内存 //所以,没有对象,也可以获取变量的值,这里传null也是可以的。 int id = (int) field.get(null);
2.通过反射获取定义的注解的值
1)获取成员变量的注解以及值。
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface BindView { int value(); }
public class MainActivity { @BindView(10000) TextView textView; }
//10通过反射拿到定义在属性上的注解 Class clazz = MainActivity.class; Field textView = clazz.getDeclaredField("textView"); BindView bindView = textView.getAnnotation(BindView.class); int txtId = bindView.value();
3)通过反射获取定义在方法和方法参数上的注解以及值
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Post { String value() default ""; }
public interface NetWorkInterface { @Post("http://www.baidu.com") Call getPerson(@Queue("name") String name, @Queue("200") int price); }
//11通过反射拿到方法上定义的注解 clazz = NetWorkInterface.class; Method method = clazz.getMethod("getPerson", String.class, int.class); //获取Post注解 Post post = method.getAnnotation(Post.class); //获取值 String url = post.value();
//12通过反射拿到参数上的注解 //为是个二维数组,因为方法参数会有多个,一个参数有可能定义多个注解 Annotation[][] annotations = method.getParameterAnnotations(); for (Annotation[] ans : annotations) { for (Annotation an : ans) { if (an instanceof Queue) { Queue queue = (Queue) an; String value = queue.value(); } } }
4)获取方法的参数和返回值类型。
//13.拿到方法参数的类型。 Type[] types = method.getGenericParameterTypes(); for (Type type : types) { System.out.println(type.toString()); } //14.获取方法返回值类型 Type type = method.getGenericReturnType();
3总结:通过反射,可以拿到对象身上的成员变量的值、调用方法,获取定义在成员变量、方法和 方法参数上的注解。Retrofit 就用到了注解加反射技术,和动态代理(这个技术稍后分享)
4.通过反射,可以做到以上事情。反射的原理是啥?
1)我们写的源代码是.java文件,通过javac编译后成为.class文件,即字节码文件。
2)程序执行时,JVM会类加载字节码文件到内存,严格意义上说是加载到方法区,并转换成
java.lang.Class对象。万事万物皆对象,Class被称为类对象,描述类在元数据空间的数据结构,包含类中定义的属性、方法、构造方法、注解、接口等信息。
所有反射的第一步是拿到类对象Class对象。拿到了Class对象,也就拿到了类中定义的一切。
Class clazz = Class.forName("com.example.lib.Person");
这行代码就是通过类加载器把Person类加载到内存,并得到对应的Class 对象。
到此这篇关于Java反射机制介绍的文章就介绍到这了,更多相关Java反射内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 2亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 3现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 4如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 5AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 6转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 7充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 8好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 9名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 10亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战