反射的作用:通过反射获取属性和方法

今天主要来谈一谈反射中获取成员方法和成员变量的主要方法:

在获取之前我们首先创造两个类

Person类(父类):

 1 public class Person {
 2     private String name;//私有属性
 3     public Integer age;//公共属性
 4     
 5     public String getName() {
 6         return name;
 7     }
 8     
 9     public void setName(String name) {
10         this.name = name;
11     }
12     
13     public Person() {//空参构造
14         super();
15     }
16     
17     public void paaa() {//公共方法
18         
19     }
20     
21     private void pbbb() {//私有方法
22         
23     }
24 }

son类(子类):

 1 public class son extends Person{//集成Person类
 2     private int age;//私有属性
 3     private String name;
 4     public String cname;//公共属性
 5     public void saaa() {//公共方法
 6         
 7     }
 8     
 9     private void sbbb() {//私有方法
10         
11     }
12 }

 前言:获取Class(反射)的三种方式以及获取对应对象的一个方法:

 

 

我们可以通过上述三种方法获取相对应的class,如果想要通过class获取对应的对象,就需要用newInstance方法:

    

1、获取父类和子类中的内容(公共的):

  1)、获取父类和子类中的成员变量: 

1 public static void getFields() throws ClassNotFoundException {
2     Class<?> son = Class.forName("com.offcn.wh.reflect.son");
3     Field[] fields = son.getFields();
4     for (Field field : fields) {
5         System.out.println(field);
6     }
7 }
  
  结果如下
      
    根据结果可以看出获取了父类和子类中的公共成员变量

  2)、获取父类和子类的成员方法:

1 public static void getMethod() throws ClassNotFoundException {
2     Class<?> son = Class.forName("com.offcn.wh.reflect.son");
3     Method[] methods = son.getMethods();
4     for (Method method : methods) {
5         System.out.println(method);
6     }
7 }
  结果如下
    

       根据结果可以看出此方法获取的是所有“上”类中的方法

    3)、获取构造方法: 

1 public static void constructor() throws Exception {
2     Class<?> son = Class.forName("com.offcn.wh.reflect.son");
3     Constructor<?>[] constructors = son.getConstructors();
4     for (Constructor<?> constructor : constructors) {
5         System.out.println(constructor);
6     }
7 }
  结果如下
    

     根据结果可以看出此方法获取的是本类的所有构造方法

 

 其实能获取的还有很多,比如本类的接口等等,大家可以尝试一下,基本上类中有的东西都可以获取到

2、获取子类中的私有内容

  通过getDeclaredxxx的方法(又称为暴力反射)来获取,比如说变量:

1 public static void getFields() throws ClassNotFoundException {
2     Class<?> son = Class.forName("com.offcn.wh.reflect.son");
3     Field[] fields = son.getDeclaredFields();
4     for (Field field : fields) {
5         System.out.println(field);
6     }
7 }
  结果如下
      

    根据结果可以看出此方法获取的是本类的所有所有属性  

3、改变子类中的私有内容(以私有属性为例)   

   我们通过暴力反射获取了私有内容后会发现根本无法使用,会报如下图的错误:

   代码:

1 public static void setFields() throws Exception{
2     Class<?> class1 = Class.forName("com.offcn.wh.reflect.Son");
3     Son son = (Son) class1.newInstance();//通过反射拿到对象
4     Field field = class1.getDeclaredField("name");//根据属性名称获取属性
5     field.set(son, "wh");//与son.setName("wh")相同
6     System.out.println(son.getName());
7 }

   错误:

  

  

   这时就需要设置私有属性的Accessible属性为true,然后再进行修改

  

 

4、获取父类中的私有属性、方法

  在上边的实例中我们获取了除父类私有内容外的所有内容,下面我们就来获取一下父类的私有内容(以私有方法为例)

  getField只能获取本类和父类中的所有属性,getDeclaredField只能获取本类的所有属性,所以要想获取父类的私有属性只有先去获取父类的字节码对象

  获取父类的方法:getSuperclass();

  具体代码如下:

1 public static void getSuper() throws ClassNotFoundException {
2     Class<?> son = Class.forName("com.offcn.wh.reflect.Son");
3     Class<?> superclass = son.getSuperclass();//获取父类字节码对象
4     Field[] fields = superclass.getDeclaredFields();//获取父类的所有属性
5     for (Field field : fields) {
6         System.out.println(field);
7     }
8 }

5、总结

  我们只要掌握了反射,就可以获取类的字节码对象,然后通过方法获取类中的内容,getxxx()为获取本类和父类的公共方法,getDeclaredxxx()为获取本类的所有内容,如果想修改或者使用私有内容,就需要设置xxx.setAccessible(true)来获取访问权限,对于父类的私有内容我们可以通过getSuperclass()来获取父类的字节码对象,然后再去获取私有内容。

  我的个人公众号会不定时更新我的java学习之路,大家如果也在学习java可以在公众号上边与我交流哦。

猜你喜欢

转载自www.cnblogs.com/apbddpz/p/11255182.html