如何编写一个构造函数来阻止在某些条件下创建对象

时间:2016-02-03 05:39:42

标签: java object constructor

我正在尝试为继承另一个对象的对象创建构造函数,但是这个构造函数也应该阻止在某些条件下创建对象。

我有这段代码:

class Foo
{
    double x;
    public Foo(double init_x)
    {
        x = init_x;
    }
}

class Bar extends Foo
{
    public Bar(double init_x)
    {
        if(init_x < 10)
        {
            throw new Exception();
        }
        super(init_x);
    }
}

以下是使用主要定义编译代码时的错误:

test2.java:13: error: constructor Foo in class Foo cannot be applied to given types;
        {
        ^
  required: double
  found: no arguments
  reason: actual and formal argument lists differ in length
test2.java:18: error: call to super must be first statement in constructor
            super(init_x);
                 ^
2 errors

我的问题是:即使我明确指定了Bar(double init_x),为什么我会得到第一个错误?如果超级调用必须是第一个语句,那么为什么我会得到第二个错误?那么我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

您有两种选择:

  1. 您将支票移至调用super之后。它仍然在方法完成之前,因此调用者将看不到构造的对象 - 它至少在调用者的视图中阻止了构造:

    class Bar extends Foo {
        public Bar(double init_x) throws Exception {
            super(init_x);
            if (init_x < 10) {
                throw new Exception();
            }
        }
    }
    
  2. 您在另一个方法中进行检查,如果值正确则返回该值,但如果不正确则抛出异常:

    class Bar extends Foo {
        private static double checkInitX(double init_x) throws Exception {
            if (init_x < 10) {
                throw new Exception();
            }
            return init_x;
        }
    
        public Bar(double init_x) throws Exception {
            super(checkInitX(init_x));
        }
    }
    

    您可以在调用super中调用任何方法,该方法不是您正在构造的对象的实例方法。放置该方法的好地方是在类中作为静态方法。

  3. 但通常情况下,选项1是最好的。除非有一个很好的理由不使用超出范围的值调用超级(例如,超级构造函数非常慢,或者如果值超出范围则抛出另一个,令人困惑的异常),选项2是不必要。 (在提到的两个案例中,你最好重构超类构造函数)

答案 1 :(得分:0)

答案在您收到的错误消息中说明:error: call to super must be first statement in constructor

答案 2 :(得分:0)

我相信在构造函数中抛出异常不是好习惯。 原因,这只是我的观点,但我认为,制作简单的工厂方法会更好:

class Bar extends Foo
{
    //hide constructor
    private Bar(init_x){
        super(init_x);
    }

    //factory method
    public static Bar createBar(double init_x)
    {
        if(init_x >= 10)
        {
            return new Bar(init_x);
        }else{
            //you can return null, instead of throwing exception
            throw new Exception();            
        }
    }
}

当你需要bar的实例时:

public static void main(String [] args){

    Bar bar = Bar.createBar(104.3);
    ...
}