如果构造函数的参数是非法的,则防止实例化类?
我有一个公共构造函数,它接受一个参数(int age)来创建一个对象。 我想检查传递的参数是否合法,例如年龄不能为负。 如果它是非法的,那么就不要创建对象/实例。 如果合法,没问题。
我只能想到一种方法 –
使构造函数私有化。 使用参数(int age)创建一个静态方法来执行所有检查,如果传递非法值,则返回null。 如果您传递合法值,则创建一个对象并返回其引用。 这样做还有其他方法吗? 也许来自构造函数本身?
编辑:我想到了上述方法的一个问题。 出于显而易见的原因,工厂方法/对象创建器方法只能是静态方法。 如果工厂方法必须访问成员变量(进行一些检查)来创建对象,会发生什么? 然后,我们将被迫使该成员变量静态。 在所有情况下这可能都不合适。
是否有意义 ?
这样做还有其他方法吗? 也许来自构造函数本身?
是。 我建议从构造函数中抛出一个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; } }
编辑:
您也可以使用Till Helge Helwig建议的IllegalArgumentException
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; } }
考虑这个例子,这是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
Joshua Bloch的Effective Java 2nd Edition, Item 38: Check parameters for validity
Joshua Bloch也是上述代码的作者
为此目的使用静态工厂会更好。 因为从构造函数中抛出exception并不是一个好主意。
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 } }
如果参数是非法的,则抛出Exception
。
public Test(int age) throws IllegalArgumentException { if(age<0) throw new IllegalArgumentException(...); this.age = age; }