Вы можете сделать это с помощью Reflection (java.lang.reflect
).
Как описано в этой статье . В основном, учитывая этот класс, который имеет частных членов:
public class Secret {
private String secretCode = "It's a secret";
private String getSecretCode(){
return secretCode;
}
}
С помощью Reflection вы можете получить доступ ко всем его членам (включая частных), включая их значения. И поэтому вы просматриваете все элементы данных, чтобы увидеть, на что они ссылаются (и, конечно, вы можете повторить процесс, если они также ссылаются на другие объекты). Вот как получить доступ к их членам (в этом коде также показаны методы, которые вам, вероятно, не понадобятся, если вы просто заинтересованы в данных, но я не видел веских причин для того, чтобы вытащить эту часть):
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class Hacker {
private static final Object[] EMPTY = {};
public void reflect(Object instance)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class secretClass = instance.getClass();
// Print all the method names & execution result
Method methods[] = secretClass.getDeclaredMethods();
System.out.println("Access all the methods");
for (int i = 0; i < methods.length; i++) {
System.out.println("Method Name: " + methods[i].getName());
System.out.println("Return type: " + methods[i].getReturnType());
methods[i].setAccessible(true);
System.out.println(methods[i].invoke(instance, EMPTY) + "\n");
}
// Print all the field names & values
Field fields[] = secretClass.getDeclaredFields();
System.out.println("Access all the fields");
for (int i = 0; i < fields.length; i++){
System.out.println("Field Name: " + fields[i].getName());
fields[i].setAccessible(true);
System.out.println(fields[i].get(instance) + "\n");
}
}
public static void main(String[] args){
Hacker newHacker = new Hacker();
try {
newHacker.reflect(new Secret());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Я исправил ошибку в их исходном коде и сделал небольшое изменение, чтобы сделать более ясным, что Hacker
никоим образом не привязан к Secret
(кроме как в main
).
Обновление : Перескажите ниже свой вопрос о полях из базовых классов, вот обновленный Hacker
, который делает это (я предположил, что вы не хотите пытаться перечислять поля на Object
вот я и остановился):
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class Hacker {
private static final Object[] EMPTY = {};
public void reflect(Object instance)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class cls = instance.getClass();
while (cls != null && cls != Object.class) {
System.out.println("From class: " + cls.getName());
// Print all the method names & execution result
Method methods[] = cls.getDeclaredMethods();
System.out.println("Access all the methods");
for (int i = 0; i < methods.length; i++) {
System.out.println("Method Name: " + methods[i].getName());
System.out.println("Return type: " + methods[i].getReturnType());
methods[i].setAccessible(true);
System.out.println(methods[i].invoke(instance, EMPTY) + "\n");
}
// Print all the field names & values
Field fields[] = cls.getDeclaredFields();
System.out.println("Access all the fields");
for (int i = 0; i < fields.length; i++){
System.out.println("Field Name: " + fields[i].getName());
fields[i].setAccessible(true);
System.out.println(fields[i].get(instance) + "\n");
}
// Go to the base class
cls = cls.getSuperclass();
}
}
public static void main(String[] args){
Hacker newHacker = new Hacker();
try {
newHacker.reflect(new Secret());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
В сочетании с
public class BaseSecret {
private String baseSecretCode = "It's a base secret";
}
и
public class Secret extends BaseSecret {
private String secretCode = "It's a secret";
private String getSecretCode(){
return secretCode;
}
}
вы получите:
$ java Hacker
From class: Secret
Access all the methods
Method Name: getSecretCode
Return type: class java.lang.String
It's a secret
Access all the fields
Field Name: secretCode
It's a secret
From class: BaseSecret
Access all the methods
Access all the fields
Field Name: baseSecretCode
It's a base secret