2013-05-29 4 views
3

У меня есть класс, как показано ниже.Получение полей подкласса с использованием суперкласса с использованием отражения?

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? Мне нужно получить поля Student, используя экземпляр Emp.

мы можем получить супер полей класса, как показано ниже:

subClass.getClass().getSuperclass().getDeclaredFields(); 

аналогично я могу получить вложенные поля класса с использованием супер-класс?

Возможно ли это?

Спасибо!

+1

Нет, это не возможно, чтобы получить информацию о дочерних классах от родительского класса, так как родительский класс (по праву) не знает, какие классы его расширят. – nitegazer2003

ответ

2

В теории существует очень сложный и дорогостоящий способ пути извлечения all loaded classes и проверок, какие из них получены из Emp и содержат поле. Если нужный класс еще не загружен, это может не помочь.

3

Возможно, я неправильно понял ваш вопрос. Вы хотите сделать что-то вроде следующего?

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 является либо неполной, либо ошибочной.

+0

+1 Я согласен, что здесь может быть некоторая путаница в отношении того, как работают классы. Либо * экземпляр * является «учеником», поэтому ссылка может быть просто опущена, или это не так, и поэтому никакого поля «меток» вообще нет. Отражение в этом не происходит. –

1

Не напрямую, вам нужно написать вспомогательный метод.

Вы берете класс и имя поля (и, возможно, тип) в качестве параметров, а затем ищите это поле в данном классе. Если вы не можете найти его, вы возьмете суперкласс класса и повторите его с самого начала. Вы делаете это до тех пор, пока не найдете поле или getSuperClass() не вернули null (это означает, что вы достигли корня дерева наследования).

В этом примере показано, как вызвать поиск и вызов указанного метода на объект. Вы можете легко извлечь и адаптировать логику для полей.

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; 
} 
1

Это то, что вы хотите? Но остерегайтесь использования 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(); 
     } 
} 
0

Это окончательное решение!

@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] 
Смежные вопросы