Предотвращение создания экземпляра класса, если аргумент для конструктора является незаконным?
У меня есть открытый конструктор, который принимает параметр (int age) для создания объекта. Я хочу проверить, является ли переданный параметр законным или нет, например, возраст не может быть отрицательным. Если это незаконно, то не создавайте объект/экземпляр. Если это законно, не проблема.
Я могу только думать об одном способе сделать это -
Сделать конструктор закрытым. Создайте статический метод с параметром (int age), чтобы выполнить все проверки и вернуть null, если вы передадите ему незаконное значение. Если вы передадите ему юридическое значение, создайте объект и верните его ссылку.
Есть ли другой способ сделать это? Может быть, внутри самого конструктора?
РЕДАКТИРОВАТЬ:
Я думал об одной проблеме с указанным выше методом. Метод создателя метода/объекта factory может быть только статическим методом по очевидным причинам. Что произойдет, если метод factory должен получить доступ к переменной-члену (чтобы выполнить некоторую проверку) для создания объекта? Затем мы будем вынуждены сделать эту переменную-членом статической. Во всех случаях это может быть не совсем нормально.
Имеет ли смысл?
Ответы
Ответ 1
Есть ли другой способ сделать это? Может быть, внутри самого конструктора?
Да. Я предлагаю выбросить Exception
из конструктора
public class Person
{
int age;
public Person(int age) throws Exception
{
if(age <= 0)
{
throw new Exception("Age is not allowed");
}
// Do some stuffs
this.age = age;
}
}
Edit:
Вы также можете использовать IllegalArgumentException
, как предложено Till Helge Helwig
public class Person
{
int age;
public Person(int age) throws IllegalArgumentException
{
if(age <= 0)
{
throw new IllegalArgumentException("Age is not allowed");
}
// Do some stuffs
this.age = age;
}
}
Ответ 2
Рассмотрим этот пример: реализация java.util.HashMap
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
table = new Entry[capacity];
init();
}
см. больше в Effective Java 2nd Edition, Item 38: Check parameters for validity
Джошуа Блоха, который также является автором вышеуказанного кода
Ответ 3
Для этого лучше использовать статический factory. Потому что бросать исключение из конструктора не очень хорошая идея.
public class Person
{
public static Person newPerson(int age) /* throws SomeException -- if you want */ {
if (age <= 0 || age >= 150) {
return null; // or throw an Exception - it is how you want
}
return new Person(age);
}
private Person(int age) {
// assign age to field value
}
}
Ответ 4
Скорее бросьте Exception
, если параметр является незаконным.
public Test(int age) throws IllegalArgumentException {
if(age<0)
throw new IllegalArgumentException(...);
this.age = age;
}