Java - иерархия универсальных классов и перегрузка универсальных методов - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть (неабстрактная) базовая база class A<L,M>, абстрактная универсальная субмарина class B<K, L, M> extends A<L,M> и (не абстрактная) class C extends B<Integer, Integer, Void>:

public class A<L,M> { }

public abstract class B<K, L, M> extends A<L,M> { }

public class C extends B<Integer, Integer, Void> { }

У меня есть класс utils, в котором есть несколько методов, здесь уместны два:

public static <K, L, M> void doSomething(B<K, L, M> b) {...}
public static <L, M>    void doSomething(A<L, M>    a) {...}

Для ясности, оба метода имеют одно и то же имя.
Если я вызываю doSomething(c); (где C c), то это происходит так, как и ожидалось для 1-го метода.
Моя проблема со следующим кодом (в другом классе, который использует утилиты):

private void doSomethingMoreComplex(A a) { // a is actually C
    Utils.doSomething(a);
}

Так что здесь a на самом деле C, но это касается второго метода, я не уверен, допустил ли я ошибку в коде или это действительно ожидаемое поведение.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Это ожидаемое поведение. Тип времени выполнения a не имеет значения, так как разрешение этого метода выполняется во время компиляции. Поскольку doSomething(B) нельзя применить к аргументу типа A, метод разрешается в doSomething(A).

Вы можете справиться с этим самостоятельно, явно понижая a:

private void doSomethingMoreComplex(A a) { // a is actually C
    if (a instanceof B) {
        Utils.doSomething((B) a);
    } else {
        Utils.doSomething(a);
    }
}

... но, ну, одним словом - гадость.

Более идиоматическим способом решения этой проблемы было бы использование doSomething в качестве метода A и переопределения ( без перегрузки ) в B.

0 голосов
/ 06 ноября 2018

или это действительно ожидаемое поведение.

Да, это ожидаемое поведение.

Компилятор выбирает, какой метод запускается, и он не знает, что это B (потому что вы сказали, что это A). Так что он не знает, безопасна ли первая перегрузка, но знает, что вторая перегрузка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...