反射的基本使用
来源:互联网 发布:团购网站 淘宝折扣 编辑:程序博客网 时间:2024/05/14 14:51
在使用之前我们先想一下反射的作用,网上各种解读比较多,我认为反射的作用就是,当无法直接使用一个类的属性,构造器,方法时,我们通过反射来实现,反射可以获得一个类的所有信息。比如你想调用某个API,但是这个API在源码里用了@hide来标注,这时我们就用反射间接的来使用这个API。
使用反射有两个大的步骤,一是获取该类对应的字节码文件,即Class对象,二是获取该类的信息,即属性,方法,构造器。当然除了获取,我们也可以调用。比如我们这里有一个Person类,我们用反射来获取它的各种信息。
package com.xn.reflect;public class Person{ public int age; public String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(int age, String name) { super(); this.age = age; this.name = name; } public Person() { super(); } public void method1() { System.out.println("this is method1"); } public void method2() { System.out.println("this is method2"); }}
一:获取Class对象
1.1 、通过Object.getClass()方法
/** * 第一种获取Class对象的方法,Object的getClass方法 */ public static Class getClass1(){ Person person=new Person(); Class class1 = person.getClass(); return class1; }
1.2、通过Object类的静态属性来获取
/** * 第二种获取Class对象的方法,通过Object的静态属性来获取 */ public static Class getClass2(){ Class class1 = Person.class; return class1; }
1.3、通过Class的静态方法来获取
/** * 第三种获取Class对象的方法,通过Class的静态方法来获取 */ public static Class getClass3(){ Class class1; try { class1 = Class.forName("com.xn.reflect.Person"); return class1; } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
我们打印一下,看是否得到的同一个对象。
public static void main(String[] args) { System.out.println(getClass1()==getClass2()); System.out.println(getClass2()==getClass3()); }
打印结果如下:true true
二:获取该类的信息(属性,构造器,方法)
这里有个技巧就是通过getXXX,获取的都是共有的,即用public ,protect声明的,若要是获取私有的属性,,方法,构造器,我们就要使用getDeclaredXXX来获取。
2.1、获取类的构造器,并通过构造器来获取类的实例
有两种方式来获取,实际上可以通过Class的方法newInstance方法和通过构造器对应的类Constructor来获取,但是newInstance这个方式是用无参的构造函数来获取实例的。如果是有参的函数则要通过Constructor的方法来获取,下面直接上代码。注释也比较解释得比较详细。
/** * 使用反射得到构造器,一般我们使用构造函数来获取该的实例 */ public static void getConstruct() { Class clazz=null; try { //第一种方式,当构造函数是无参的时候 //得到Person对应的字节码对象 clazz = Class.forName("com.xn.reflect.Person"); //通过newInstance()方法得到,默认是调用该类的无参的构造方法,如果当我们的 Person person = (Person) clazz.newInstance(); //第二种方式,当构造函数是有参的时候 Class[]clazzs={int.class,String.class}; Constructor constructor = clazz.getConstructor(clazzs); Person p1=(Person) constructor.newInstance(new Object[]{"","喝喝"}); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
2.2、通过反射获取该类所声明的属性
可以通过反射来获取该类属性,即使是用private声明的私有属性都可以获取得到。同样是先获取字节码的对象然后,获取属性,进而获取属性的值.
/** * 使用反射机制来获取类 的属性 */ public static void getField(){ try { //获得字节码文件 Class clazz = Class.forName("com.xn.reflect.Person"); Field field = clazz.getDeclaredField("age"); //暴力访问,忽略权限控制符 field.setAccessible(true); //获取类对象 Object object=clazz.newInstance(); //为属性赋值 field.setInt(object, 24); Object o=field.get(object); System.out.println(o); } catch (Exception e) { e.printStackTrace(); } }
我们这里做的操作是这样的,首先获取字节码对象,然后获取该类的对象,再获取该类的属性,我们给属性赋值,再把属性打印出来,最后调试的结果是24。
我们要注意的是getDeclaredField该方法是Field及Method及Constructor的父类对应的方法,setAccessible(boolean flag) 是表示访问忽略访问控制符,调用之后可以访问私有的,也就是private修饰的方法或属性,Method也是一样。
2.3、通过反射来获取方法,并进行调用。
/** * 通过反射来获取的方法,并进行调用 */ public static void getMethod(){ //获得字节码文件 try { Class clazz = Class.forName("com.xn.reflect.Person"); Method method = clazz.getDeclaredMethod("method1", null); method.setAccessible(true); Object obj=clazz.newInstance(); method.invoke(obj, null); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
注意的一点就是获取方法的时候,和调用的时候,要传入参数列表,要是没有就传null,见上面的clazz.getDeclaredMethod(“method1”, null),这里传的是参数类型的字节码对象,和method.invoke(obj, null)这里传的是实参。
- 反射的基本使用
- 反射的基本使用
- 反射的基本使用
- 反射的基本使用
- 反射的基本使用
- java反射的基本使用
- 反射的基本使用实例
- 反射的基本使用实例
- java 反射的基本使用
- java反射的基本使用
- JAVA反射的基本使用
- 反射 reflection基本使用
- 反射的基本调用
- 反射的基本API
- 反射的基本应用
- 反射的基本用法
- java中反射基本的方法以及使用
- python中反射4种方法的基本使用
- Vue Vue-Cli
- 【复习笔记】手写三种O(n^2)的基础排序算法
- [px4仿真]单独启动编译和Gazebo仿真器
- quota限制用户空间
- 最少拦截系统
- 反射的基本使用
- No symbol table is loaded. Use the "file" command 解决方案
- jq三级联动
- HDU 2825-Wireless Password(AC自动机+状压DP)
- 51NOD-最大子段和问题
- 大数据环境下该如何优雅地设计数据分层
- 浅析点直播流媒体传输协议之 —— HLS(HTTP Live Streaming)
- Extjs基础
- iOS编程学习二十一(网络和JSON解析)