Метод isaccessible отражения Java

Я учусь отражение. Когда я выполняю следующий код:

package main;

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws NoSuchFieldException, SecurityException {

        Base firstBase = new Base();
        Field firstBaseField = firstBase.getClass().getDeclaredField("protectedBuffer");
        System.out.println(firstBaseField.isAccessible());

    }
}

Это базовый класс:

package main;

public class Base {

    private StringBuffer buffer;
    protected StringBuffer protectedBuffer;
    public StringBuffer buffer2;

}

результат false. Но это не должно быть правдой, потому что я могу получить доступ protectedBuffer таким образом: firstBase.protectedBuffer?

4 ответов


это потому, что вы не проверяете, является ли поле protectedBuffer доступен, когда вы делаете firstBaseField.isAccessible();

здесь происходит то, что вы проверяете значение AccessibleObject который является базовым классом для поля. Этот флаг не говорит вам, доступно ли поле модификаторами доступа java, он говорит вам, игнорируются ли эти модификаторы в настоящее время.

когда вы получаете false на firstBaseField.isAccessible() это просто означает, что правила доступа java все еще существуют и не переопределены отражением механизмы.

setAccessible()

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

редактировать

чтобы проверить, доступно ли поле java access модификаторы, вы можете попробовать получить к нему доступ и поймать IllegalAccessException, как в примере ниже.

Field field = instance.getClass().getDeclaredField("someField");
//  IllegalAccessException
field.get(instance);

вы неправильно понимаете этот доступен флаг. Согласно документация когда доступно true, все проверки доступа обходятся (вы можете использовать это поле или метод, и Java не будет проверять, является ли оно общедоступным или нет). Если Access имеет значение false, проверки доступа работают. И как написано в документации, это false по умолчанию любой AccessibleObject (даже для public полей или методов).


по умолчанию все Fields получены с помощью Class#getDeclaredField(String name) есть accessible флаг установлен в false. Вы также получите false для public поле buffer2.

на Field class является подклассом AccessibleObject:

по умолчанию отраженным объектом является не работает.


начиная с Java 9 isAccessible метод устарел. Вы можете использовать canAccess вместо.