2013-09-16 2 views
2

В одном API я использую У меня есть абстрактный класс (Класс), который имеет частное поле (A.privateField). Класс Bрасширяет класс A в рамках API. Мне нужно расширить класс B с моей его реализацией, Класс C, но мне нужен privateField класса A. Мне нужно использовать отражение: как я могу получить доступ к закрытому полю супер-класса?Как получить доступ к закрытому полю суперкласса суперкласса с отражением в Java?

Class A 
    - privateField 
Class B extends A 
Class C extends B 
    + method use A.privateField 
+0

Я думаю, что частное поле класса A может быть p вместо частного, вместо того, чтобы использовать его, вы можете получить доступ к нему из класса C без отражения. – conca

ответ

5

Тот факт, что вам нужно это сделать, указывает на ошибочный дизайн.

Однако, это может быть сделано следующим образом:

class A 
{ 
    private int privateField = 3; 
} 

class B extends A 
{} 

class C extends B 
{ 
    void m() throws NoSuchFieldException, IllegalAccessException 
    { 
     Field f = getClass().getSuperclass().getSuperclass().getDeclaredField("privateField"); 
     f.setAccessible(true); // enables access to private variables 
     System.out.println(f.get(this)); 
    } 
} 

вызовов с:

new C().m(); 

Один способ сделать «идущий вверх по иерархии классов» Анджей Doyle толкует является следующим:

Class c = getClass(); 
Field f = null; 
while (f == null && c != null) // stop when we got field or reached top of class hierarchy 
{ 
    try 
    { 
    f = c.getDeclaredField("privateField"); 
    } 
    catch (NoSuchFieldException e) 
    { 
    // only get super-class when we couldn't find field 
    c = c.getSuperclass(); 
    } 
} 
if (f == null) // walked to the top of class hierarchy without finding field 
{ 
    System.out.println("No such field found!"); 
} 
else 
{ 
    f.setAccessible(true); 
    System.out.println(f.get(this)); 
} 
+0

+1 Кроме того, если поле просто находится на «суперклассе», не зная точно, что вы можете подобрать иерархию классов, проверяя каждый класс в свою очередь, чтобы увидеть, содержит ли оно это поле (пока вы не нажмете «Объект»). –

+0

Спасибо! Я начинаю использовать рефлексию, и это действительно полезный старт! –

+0

Да, это суть того, что я имел в виду (комментарии не подходят для кода). Однако 'while (true)' означает, что цикл может только закончиться исключением (и в конечном итоге будет вызывать NPE, если поле не найдено). 'while (c! = null)' будет лучшим условием –

Смежные вопросы