Явно устранение неоднозначности перегруженного конструктора в Java

Я знаю, что если у меня есть перегруженный метод в 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 ответа

Но нужно сделать 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 каждый раз... если это уместно.

Если оба A а также B интерфейсы, это будет работать

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

    new MyClass(null); // the 3rd constructor is chosen, which calls the 2nd
Другие вопросы по тегам