记一次Java反射以及演示在设置暴力反射权限后,如何获取和设置给指定私有的属性赋值

文档底部附上它处反射总结以及暴力反射的演示
说明:以下代码没问题能运行,但还有部分内容没学完,较为潦草。此文分为Person类和reflectDemo2 两个类。

------------------------------------ 代码分割线 -----------------------------------------
package com.itcast.domain;

public class Person {
private String name;
private int age;

public String a;
protected String b;
String c;
private String d;

public String getD() {
    return d;
}
public void setD(String d) {
    this.d = d;
}

public Person() {
}

public Person(String name, int age, String d) {
    this.name = name;
    this.age = age;
    this.d = d;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

@Override
public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", a='" + a + '\'' +
            ", b='" + b + '\'' +
            ", c='" + c + '\'' +
            ", d='" + d + '\'' +
            '}';
}

}

---------------------------------- 代码分割线 ---------------------------------------------
package com.itcast.reflect;

import com.itcast.domain.Person;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

//@SuppressWarnings("ALL")
public class reflectDemo2 {
/**

  • 1、获取成员变量们
    Field[] getFields():获取所有public修饰的成员变量
    返回一个数组包含 Field物体反射的类或接口的 类对象代表所有可访问的公共领域。
    Field getField(String name):获取指定public修饰的成员变量
    返回一个 Field对象反映的类或接口的 类对象表示的指定公共成员。
    Field[] getDeclaredFields():获取所有的变量,不考虑修饰符
    Field[] getDeclaredField(String name):获取指定的变量,要考虑修饰符,即需要进行暴力反射

  • 2、获取构造方法们
    Constructor getConstructor(类<?>... parameterTypes)
    返回一个 Constructor对象反映指定的公共构造函数的 类对象表示的类。
    Constructor<?>[] getConstructors()
    返回一个数组包含 Constructor物体反射所有的 类对象表示的类的公共构造函数。

Constructor getDeclaredConstructor(类<?>... parameterTypes)
返回一个 Constructor对象反映指定的构造函数的类或接口的 类对象表示。
Constructor<?>[] getDeclaredConstructors()
返回 Constructor物体反射所有的构造函数通过 类对象表示的类中声明一个数组。

  • 3、获取成员方法
    方法 getMethod(String name, 类<?>... parameterTypes)
    返回一个 方法对象反映的类或接口的 类对象表示的指定公共成员方法。
    方法[] getMethods()
    返回一个数组包含 方法物体反射所有的类或接口的 类对象表示的公共方法,包括那些由类或接口的超类和超接口继承的声明。

方法 getDeclaredMethod(String name, 类<?>... parameterTypes)
返回一个 方法对象反映指定声明方法的类或接口的 类对象表示。
方法[] getDeclaredMethods()
返回一个数组包含 方法物体反射所有声明的方法的类或接口的 类对象,代表包括公众、保护,默认(包)的访问,和私有方法,但不包括继承的方法。

  • 4、获取类名
    String getName()
    */

    public static void main(String[] args) throws Exception {

     //0、获取Person的Class对象
     Class personClass = Person.class;
     /**
      *          * 1、获取成员变量们
      *         Field[] getFields()
      *         Field getField(String name)
      *         Field[] getDeclaredFields()
      *         Field[] getDeclaredFields(String name)
      */
     //1、 Field[] getFields() 获取所有public修饰的成员变量
     Field[] fields = personClass.getFields();
     for (Field field:fields) {
         System.out.println(field);
     }
    
     System.out.println("----------------");
     Field a = personClass.getField("a");
     //获取变量a的值
     Person p = new Person();
     Object value = a.get(p);
     System.out.println(value);//null
     //设置a的值
     a.set(p,"张三");
     System.out.println(p);//Person{name='null', age=0, a='张三', b='null', c='null', d='null'}
    
     System.out.println("====================");
     // Field[] getDeclaredFields():获取所有的变量,不考虑修饰符
     Field[] declaredFields = personClass.getDeclaredFields();
     /**
      * for(元素类型t 元素变量x : 遍历对象obj){
      * 引用了x的java语句;
      * }
      */
     for (Field declaredField : declaredFields) {
         System.out.println(declaredFields);
     }
    
     System.out.println("============");
    
    
     Field d =  personClass.getDeclaredField("d");
     //忽略访问权限修饰符的安全检查
     //获取指定的变量,要考虑修饰符,即需要进行暴力反射
     d.setAccessible(true);//设置暴力反射权限
     Object value2 = d.get(p);
     System.out.println(value2);//null
    
     System.out.println("演示在设置暴力反射权限后,如何获取和设置给指定私有的属性赋值");
     /**
      * 演示在设置暴力反射权限后,如何获取和设置给指定私有的属性赋值
      */
     //获取字节码文件
     Class clazz = Person.class;
     //创建对象
     Object obj = clazz.newInstance();
     //获取方法
     Method getD = personClass.getDeclaredMethod("getD");
     Method setD = personClass.getDeclaredMethod("setD", String.class);
     //设置暴力访问权限
     getD.setAccessible(true);
     setD.setAccessible(true);
     Object getValue4 = setD.invoke(obj,"孤独求败");
     Object value3 = getD.invoke(obj);
     System.out.println(value3);//孤独求败
    

// * 2、获取构造方法们
// Constructor getConstructor(类<?>... parameterTypes)
// Constructor<?>[] getConstructors()
//
// Constructor getDeclaredConstructor(类<?>... parameterTypes)
// Constructor<?>[] getDeclaredConstructors()
//
// * 3、获取成员方法
// 方法 getMethod(String name, 类<?>... parameterTypes)
// 方法[] getMethods()
//
// 方法 getDeclaredMethod(String name, 类<?>... parameterTypes)
// 方法[] getDeclaredMethods()
//
// * 4、获取类名
// String getName()
//
}

}


链接:https://blog.csdn.net/wildwolf_001/article/details/79726870

上一篇:理顺 JavaScript (14) - constructor 与 instanceof


下一篇:C++ reference containers