【问题标题】:Explicitly disambiguating overloaded constructor in Java在 Java 中明确消除重载构造函数的歧义
【发布时间】:2012-11-12 00:25:07
【问题描述】:

我知道,如果我在 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);
}

【问题讨论】:

  • 有一个调用this((B)null)的无参数构造函数?
  • @Kevin 这适用于我的情况,但不适用于单参数构造函数级联到多参数构造函数的情况。

标签: java constructor null ambiguous disambiguation


【解决方案1】:

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

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

但是您可以通过将new 调用替换为static 对象工厂方法来避免这种情况;例如

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

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

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


请注意,使用工厂方法还允许您执行诸如每次返回相同的“ANull”或“BNull”MyClass 实例之类的操作……如果这样做合适的话。

【讨论】:

  • 没想到这一点,但似乎是一个不错的方法。通常使用工厂方法而不是裸构造函数会更好吗?我已经在一些库中看到了它,但在自己编写代码时总是更喜欢使用构造函数。
  • “一般来说使用工厂方法而不是裸构造函数更好吗?” - 最好使用在您正在开发的应用程序的上下文中最有效的方法.. .
【解决方案2】:

如果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

【讨论】:

  • 有趣的解决方案,不知道T 可以有多个边界这样! +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多