Конструктор перегрузки с универсальным типом параметра (расширяет и расширяет и интерфейс) - PullRequest
0 голосов
/ 12 июня 2018
A is abstract

public <T extends A> B(T parameter) {
    //...do some stuff with A features
}
public <T extends A & I> B(T parameter) {
    //...do some stuff with A and I features
}

Этот код не работал, потому что Java говорит: Стирание метода B (T) такое же, как и у другого метода в типе B

Но почему?Я не понимаюКогда у меня есть Объект A, возьмите первый Конструктор, когда A реализует I, другой ...

Я имею в виду, что вы, вероятно, хотите сказать, что в этом случае A всегда реализует I, но нет:

lookпри этом:

C1 расширяет A

C2 расширяет A

C3 расширяет A реализует I

C1 и C2 будет вызывать первый конструктор, а C3 - второй.Почему это невозможно?

Я не могу сделать это:

A is abstract

public B(A parameter) {
    //...do some stuff with A features
}
public B(I parameter) {
    //...do some stuff with I features
}

, потому что, если A реализует I, он всегда выберет первый конструктор.Если вы знаете другой способ избежать этой проблемы, пожалуйста, сообщите мне.

1 Ответ

0 голосов
/ 12 июня 2018

Это наследие.См. Этот вопрос для объяснения: Метод имеет то же самое стирание, что и другой метод в типе

Вы можете действительно решить его, только имея два разных фабричных метода с двумя разными именами:

class B {
    public static <T extends A> B create(T param) {
        return new B(/*...*/);
    }

    public static <T extends A & I> B createWithI(T param) {
        return new B(/*...*/);
    }

    private B(/*args*/) {
        //...
    }
}

или, как предложено Khelwood , используя instanceof:

class B
{
    @SuppressWarnings("unchecked")
    public <T extends A, AI extends A & I> B(T param) {
        if (param instanceof I) {
            AI ai = (AI) param;
            // A and I
        }
        else {
            // Just A
        }
    }
}
...