Предположите, что у меня есть singleton-класс во внешнем lib к моему приложению. Но тем не менее я могу создать экземпляры того конкретного класса с помощью отражения. Как это
Class clas = Class.forName(Private.class.getName());
for(Constructor c : clas.getDeclaredConstructors()){
c.setAccessible(true);
Private p = (Private) c.newInstance();
System.out.println(p);
}
Как я могу ограничить это?.
Спасибо J
Используя SecurityManager и контролируя управление ReflectPermission ("suppressAccessChecks")
( пример ).
Однако диспетчер безопасности влияет на производительность и редко используется на стороне сервера.
Короче: вы не можете .
Любой конструктор, как открытый, так и закрытый, может быть доступен с помощью отражения и может использоваться для создания экземпляра нового объекта.
Вам придется прибегнуть к другим методам, таким как SecurityManager
.
Я не думаю, что вы можете это ограничить.
Очевидно, что использование отражения для доступа к личным частям других пользователей является опасной / сомнительной практикой ( snicker ), но иногда это необходимо для различных типов инструментов и приложений.
См. Взломать любой класс Java с помощью атаки отражения и Как программно установить SecurityManager и политику безопасности Java .
Вы можете сделать это так.
private static final Private INSTANCE = new Private();
private Private() {
if(INSTANCE !=null)
throw new IllegalStateException("Already instantiated");
}
public static Private getInstance() {
return INSTANCE;
}
Если вы говорите, в частности, о синглтонах: это одна из причин, почему их лучше всего реализовать с помощью перечисления:
public enum YourSingleton {
INSTANCE;
// methods go here
}
Если вы говорите об использовании setAccessible ()
в целом: Если код написан кем-то, кому вы не доверяете, чтобы не делать таких закулисных трюков, вам все равно не следует запускать его (или запускать в песочнице). Разработчики должны рассматривать общедоступную / частную метаинформацию о том, как предполагается использовать код, а не как средство безопасности.
AFAIK, это своего рода метапрограммирование и поэтому требует проверки на другом уровне абстракции. Из Javadoc я полагаю, вам следует использовать SecurityManager для обеспечения желаемого поведения: setAccessible () . Как правило, IMHO вы должны действительно знать, что вы делаете, когда вы метапрограммируете и изменяете доступ, действительно должны есть веские причины для этого.