Есть библиотека, в ней, к примеру, есть такой класс:
public class SimpleObject {
private object;
public void setObject(Object object) { ... }
public Object getObject() { ... }
}
Рядом, в соседнем пакете, находится класс ObjectHandler
, который принимает этот объект и, на основании результата метода .getObject()
, что-то делает.
Нужно сделать так, чтобы пользователь, получив или создав объект SimpleObject
, не мог использовать метод .getObject()
(чтобы метод для пользователя был что-то вроде private
), а класс ObjectHandler
- мог и видел его.
Как это сделать?
Это нужно для того, чтобы не показывать пользователю лишние методы (и ему удобнее, и мне безопаснее). Сейчас для достижения этой цели приходится кидать объект и его обработчик в один пакет (что выглядит немного непонятно), а метод get
делать доступным в пределах пакета.
В Java нельзя "где-то сбоку" от protected
или public
(равно как и в начале файла) указать пакеты, в которых метод будет доступен. В документации говорится только при каких модификаторах есть доступ в рамках пакета, а при каких - "во всём мире".
Также нет такого понятия как "подпакет" ("sub-package"). По этому поводу на enSO есть хороший ответ.
Получается, что с помощью модификаторов доступа желаемого результата не добиться. В таком случае остаются такие варианты:
SimpleObject
и ObjectHandler
в одном пакете, если это оправданно или другие варианты не подходят.ObjectHandler
можно использовать суперкласс для SimpleObject
, содержащий необходимый функционал.Допустим, класс SimpleObject
выглядит так:
package test2;
public class SimpleObject
{
private Object object;
public void setObject(Object object) { this.object = object; }
protected Object getObject() { return object; }
}
"Костыльные" решения:
В пакете, в котором находится ObjectHandler
, создать класс MySimpleObject extends SimpleObject
и переопределить в нём нужные методы:
package test3;
import test2.SimpleObject;
public class MySimpleObject extends SimpleObject
{
protected Object getObject() { return super.getObject(); }
}
После чего использовать MySimpleObject
вместо SimpleObject
:
MySimpleObject mso = new MySimpleObject();
mso.setObject("Str");
System.out.println(mso.getObject());
"Пуститься во все тяжкие" и получать доступ к методу через рефлексию:
SimpleObject so = new SimpleObject();
so.setObject("Str");
try
{
Method method = so.getClass().getDeclaredMethod("getObject");
method.setAccessible(true);
System.out.println(method.invoke(so));
}
catch (Exception e) { }
От "глупостей" "пользователей" защититься нельзя.
Если Ваш SimpleObject
относится к уровню сущностей (@Entity
), то все его getters & setters должны быть public
. Это правильно и логично. И нет ничего плохого в том, что кто-то будет создавать и полноценно использовать Вашу сущность SimpleObject
.
Но, если SimpleObject
— это некий API-метод, то действительно нужно .getObject()
защитить от "пользователя", то есть контролировать защиту от получения некорректного значения или вызова .getObject()
в неподходящий момент по логике вашего проекта.
В таком случае, я рекомендую оставить модификатор видимости public getObject()
, но защититься от неправильного использования через Exception
.
Создайте свой Exception
или используйте существующий. Например:
public class MyLogicalException extends Exception {
public MyLogicalException(String message) {
super(message);
}
}
И объявите, что метод getObject()
может выбрасывать исключение MyLogicalException
при определенных обстоятельствах. Например:
public Object getObject() throws MyLogicalException {
if (object == null) {
throw new MyLogicalException("object не может быть пустым!");
} else {
return object;
}
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Существует wsdl файл из которого я пытаюсь сгенерировать java классы при помощи утилиты wsimportГенерация завершается ошибкой:
Здравствуйте ! Нам нужно разместить ромбы на главной странице сайта, как на картинкеКак это лучше сделать ? Попробовали несколько способов,...