Как использовать оператор try-with-resources с объектом интерфейса в Java

Я хотел бы использовать оператор try-with-resources для определения объекта интерфейса как конкретного класса. Вот пример кода, в общих чертах определяющий мой интерфейс и классы.

interface IFoo extends AutoCloseable
{
    ...
}

class Bar1 implements IFoo
{
    ...
}

class Bar2 implements IFoo
{
    ...
}

class Bar3 implements IFoo
{
    ...
}

// More Bar classes.........

Теперь мне нужно определить объект IFoo, но конкретный класс зависит от другой переменной моего кода. Логика одинакова для всех конкретных классов. Поэтому я хотел бы использовать оператор try-with-resources для определения объекта интерфейса, но мне нужно использовать условный оператор, чтобы увидеть, какой конкретный класс мне нужно определить как объект интерфейса.

Логически, это то, что я хочу сделать:

public void doLogic(int x)
    try (
        IFoo obj;
        if (x > 0) { obj = new Bar1(); }
        else if (x == 0) { obj = new Bar2(); }
        else { obj = new Bar3(); }
    )
    {
        // Logic with obj
    }
}

Единственный ресурс, который я нашел по этому поводу, - это вопрос @Denis здесь: Как использовать Try-with-resources с оператором if? Однако приведенное там решение потребует вложенных троичных операторов для моего сценария, и это очень быстро становится беспорядочным.

Кто-нибудь знает элегантное решение этой проблемы?


person FallDownT    schedule 27.03.2016    source источник


Ответы (2)


Определите фабричный метод для создания экземпляра IFoo:

IFoo createInstance(int x) {
    if (x > 0) { return new Bar1(); }
    else if (x == 0) { return new Bar2(); }
    else { return new Bar3(); }
}

затем вызовите это в своем инициализаторе try-with-resources:

public void doLogic(int x) {
  try (IFoo ifoo = createInstance(x)) {
    // Logic with obj
  }
}
person Andy Turner    schedule 27.03.2016
comment
Я добавил createInstance(...) в качестве статического метода в свой интерфейс, и он отлично работал. Спасибо! - person FallDownT; 27.03.2016

Я согласен, что лучшим решением будет написать вспомогательный метод, как в этом ответе.

Однако я также хочу отметить, что вложенные тернарные операторы не запутаны. Вам вообще не нужны скобки, и при хорошем форматировании это можно сделать похожим на оператор switch:

try (IFoo foo = x > 20     ? new Bar1() :
                x < 0      ? new Bar2() :
                x == 10    ? new Bar3() :
                x % 2 == 0 ? new Bar4() : 
                             new Bar5()) {
        // do stuff
}
person Community    schedule 27.03.2016