寫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); } }