2013-04-02 2 views
0

Я просто думал, и я подумал: поскольку контроль доступа предназначен только для защиты от атак, а не от мошенничества, мне было интересно, можно ли получить доступ к значениям скрытых переменных в Java?Private Access Control

Возьмем, к примеру

public Cat { 

public int numberOfLegs = 4; 
private int numberOfWhiskers = 42; 

} 

Можно ли найти значение numberOfWhiskers из-за пределов этого класса?

Редактировать: Я прочитал нить в ссылке, и я вижу, что с помощью SetAccesible() вы можете получить значение любого частного поля, которое вы знаете, имя. Можем ли мы найти значение поля, имя которого мы не знаем?

Примечание: это может быть выполненным на некоторых языках, таких как C++, например, с помощью указателей, итераций по полям в классе.

+0

Я несколько не согласен с вашим положением. Java, по сути, предназначен для обеспечения защиты VM от ненадежного кода, запущенного внутри него. Это то, что предназначено для менеджера безопасности и модели безопасности. Элементы управления доступом являются неотъемлемой частью модели безопасности и проверяются во время выполнения, они не просто используются во время компиляции. –

ответ

3

Вы можете использовать отражение для обхода проверки private. Используйте метод Class#getDeclaredField и метод Field#getInt (есть другие устройства доступа).

Этот код может быть в другом классе:

Cat myCat = new Cat(); 
int whiskers; 

try 
{ 
    Field field = Cat.class.getDeclaredField("numberOfWhiskers"); 
    // This line bypasses the private control 
    field.setAccessible(true); 
    whiskers = field.getInt(myCat); 
} 
catch (NoSuchFieldException e) { /* Handle */ } 
catch (IllegalAccessException e) { /* Handle */ } 

EDIT

Я видел ссылку на дубликате вопрос. Я должен согласиться, как правило, не делать этого.

ВТОРОЙ EDIT

В ответ на дополнительный отредактированной вопрос, вы можете использовать метод Class#getDeclaredFields вернуть Field[] с помощью которого можно использовать для перебора всех полей класса.

Field[] fields = Cat.class.getDeclaredFields(); 
// Iterate over the array here.