![](/img/trans.png)
[英]Getting actual generic types of “super super” class or interface using reflection
[英]Getting sub class fields using super class using reflection?
我有一個課程如下。
public class Emp{
private String name;
private String age;
//setters and getters
}
下面還有一節課。
public class Student extends Emp{
private int marks;
//setters and getters
}
無論如何使用java Reflection使用超類來獲取子類的字段? 我需要使用Emp實例獲取Student字段。
我們可以得到如下的超類字段:
subClass.getClass().getSuperclass().getDeclaredFields();
同樣可以使用超類獲取子類字段嗎?
可能嗎?
謝謝!
我可能誤解了你的問題。 你想做以下的事嗎?
Emp e = new Student(...);
[do something with e]
foo = e.marks;
如果是,請這樣做:
foo = ((Emp)e).marks;
但是,如果您想執行以下操作:
Emp e = new Emp(...);
[do something with e]
e.marks = ....
然后不,這是不可能的,我懷疑你的java對象模型的內部模型是不完整的還是有缺陷的。
不是直接的,你必須寫一個輔助方法。
您將類和字段名稱(可能還有類型)作為參數,然后在給定的類中查找該字段。 如果你找不到它,你可以從班級的超類中重復一遍。 在您找到該字段之前執行此操作,或者getSuperClass()返回null(意味着您已到達繼承樹的根目錄)。
此示例演示如何在對象上調用find並調用指定的方法 。 您可以輕松地提取和調整字段的邏輯。
public static Object call(final Object instance,
final String methodName,
final Class<?>[] signature,
final Object[] args) {
try {
if (instance == null)
return null;
Class<?> instanceClass = instance.getClass();
while (instanceClass != null) {
try {
final Method method = instanceClass.getDeclaredMethod(methodName, signature);
if (!method.isAccessible())
method.setAccessible(true);
return method.invoke(instance, args);
} catch (final NoSuchMethodException e) {
// ignore
}
instanceClass = instanceClass.getSuperclass();
}
} catch (final Throwable e) {
return null;
}
return null;
}
這是你想要的嗎? 但要注意使用field.setAccesible。
家長班:
public class ParentClass {
private String parentField = "parentFieldValue";
public void printFields() throws IllegalAccessException {
Field[] fields = getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object fieldValue = field.get(this);
if (fieldValue instanceof String) {
String stringValue = (String) fieldValue;
System.out.println(stringValue);
}
}
}
}
兒童班:
public class ChildClass extends ParentClass {
private String childField = "childFieldValue";
}
用法:
public class Main {
public static void main(String[] args) throws IllegalAccessException {
ParentClass pc = new ParentClass();
ChildClass cc = new ChildClass();
pc.printFields();
cc.printFields();
}
}
這是最終的解決方案!
@NonNull
public static List<Class<?>> getSubClasses() {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
String method = trace[3].getMethodName();
if (!"<init>".equals(method)) {
throw new IllegalStateException("You can only call this method from constructor!");
}
List<Class<?>> subClasses = new ArrayList<>();
for (int i = 4; i < trace.length; i++) {
method = trace[i].getMethodName();
if ("<init>".equals(method)) {
try {
subClasses.add(Class.forName(trace[i].getClassName()));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
} else {
break;
}
}
return subClasses;
}
這是一些用法示例:
class a {
public a(){
print(getSubClasses());
}
}
class b extends a{
}
class c extends b{
}
結果是
new a() -> []
new b() -> [b.class]
new c() -> [b.class, c.class]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.