Java通过反射访问及修改类内的私有变量
写mod的时候,界面某项功能显示定位需要用到玩家周围的boss信息,然而这个信息存储在一个私有的Map变量里,所在的类也没有提供get方法。最后发现可以利用反射获取该私有变量的值。
以下是示例代码,其中field.setAccessible(true)最为重要。
import java.util.ArrayList; import java.lang.reflect.Field; public class Test { public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { TestClass testClass = new TestClass(); // 获取TestClass对象的所有变量 Field[] fields = testClass.getClass().getDeclaredFields(); for (Field field : fields){ // 设置为为true时可访问私有类型变量 field.setAccessible(true); // 根据获取到的变量名输出变量值 // 这里的get和set可能抛出IllegalAccessException异常 switch(field.getName()){ case "integer": System.out.println("integer:" + field.get(testClass)); break; case "string": // 即使是final修饰的变量也能改变其值 field.set(testClass, "new text"); System.out.println("string:" + field.get(testClass)); break; case "arrayList": @SuppressWarnings("unchecked") ArrayList<Double> arrayList = (ArrayList<Double>) field.get(testClass); arrayList.add(5.6); for(Double d : arrayList){ System.out.println("arrayList:" + d); } } } // 也可以根据已知的变量名获取值,但是可能抛出NoSuchFieldException异常 Field field = testClass.getClass().getDeclaredField("integer"); field.setAccessible(true); field.set(testClass, 1); System.out.println("integer:" + field.get(testClass)); } } class TestClass{ public final int integer = 0; private final String string = "text"; private final ArrayList<Double> arrayList = new ArrayList<>(); public TestClass(){ arrayList.add(1.2); arrayList.add(3.4); } }