在Java中明确消除重载构造函数的歧义

时间:2012-11-12 00:25:08

标签: java constructor null ambiguous disambiguation

我知道如果我在Java中有一个重载方法可以接受几种不同类型的参数,并且我想将null传递给该方法,我需要将它显式地转换为其中一种可接受的类型。我的问题是,是否可以从方法本身中选择在null上调用该方法的哪个版本(例如,通过添加另一个重载来处理null)?

我的问题如下 - 我有一个带有重载构造函数的类,它接受一个参数:

public class MyClass {

    public MyClass(A arg) {
        // do something
    }

    public MyClass(B arg) {
        // do something else
    }
}

用例是这样的,如果类是用null构造的,那么只有构造函数的第二个版本才有意义。但每次必须做new MyClass((B)null)都容易出错。如果我不小心使用强制转换为A,则会执行错误的构造函数。我也无法在我的A构造函数中引入以下检查:

if (arg == null) {
    this((B)arg);
}

因为this(...)不是第一个声明。当然,我可以在此检查中复制B构造函数中的代码,或者引入另一种方法来执行B构造函数的操作,然后从构造函数内部和此检查中调用它,但是这似乎不是一个“干净”的解决方案(并且可能并非总是可行,例如在级联构造函数的情况下)。

我有没有办法只需要执行new MyClass(null)并且每次都执行构造函数的B版本?

我尝试添加此重载,但编译器抱怨:

public MyClass(null arg) {
    this((B)arg);
}

2 个答案:

答案 0 :(得分:4)

  

但每次必须做new MyClass((B) null)都容易出错。

如果您打算使用这样的裸构造函数,那么这是Java语言必须提供的最佳机制。

但您可以通过使用new对象工厂方法替换static调用来避免这种情况; e.g。

  public static MyClass newANull() {
      return new MyClass((A) null);
  }

  public static MyClass newBNull() {
      return new MyClass((B) null);
  }

(显然,你需要更好的方法名称......)


请注意,使用工厂方法还可以让您每次都返回相同的“ANull”或“BNull”MyClass实例......如果这是合适的事情。

答案 1 :(得分:1)

如果AB都是接口,则可以使用

    public <T extends Object&A&B> MyClass(T arg)
    {
        this((B)arg);
    }

    new MyClass(null); // the 3rd constructor is chosen, which calls the 2nd
相关问题