Статический метод Java, подстановочный знак / универсальный тип возврата - PullRequest
0 голосов
/ 25 октября 2018

Я создаю API, который использует абстрактные классы для вызова статических методов.Некоторый псевдокод Java:

public abstract class APIBaseClass {

    public static List<?> myMethod(Class<?> clazz, MyConverter converter, List<Object> objects) {
        return objects.stream()
                  .map(object -> converter.convertObjectToType(object, clazz))
                  .collect(Collectors.toList());
    }

}

И, где вызывается myMethod:

public abstract class MyAPIClass extends APIBaseClass {

    public static List<MyClassType> invokingMethod(MyConverter converter, List<Object> objects) {
        List<MyClassType> list = myMethod(MyClassType.class, converter, objects);
        ...
        return list;
    }
}

myMethod компилируется, как и ожидалось.И invokingMethod не компилируется, как и ожидалось, из-за несовместимых типов:

Required: List<blah.blah.blah.MyClassType>
Found:    List<capture<?>>

Компилируется без ошибок или предупреждений, если I: (1) @SuppressWarnings ("unchecked") на invokingMethodи (2) приведите результат myMethod к списку MyClassType, когда вызывается, то есть List<MyClassType> list = (List<MyClassType>) myMethod(MyClassType.class, converter, objects);.Тем не менее, нет никакой прозрачности, что это было бы необходимо для любого, кто использует API, который кажется менее чем идеальным.

Каковы мои варианты для myMethod, возвращая список типа, с которым он вызывается, на invokingMethod, поддерживая мои абстрактные классы и статические методы, в то же время идеально улучшая удобство использования в invokingMethod?

Любые предложения или альтернативные идеи приветствуются.

Заранее спасибо.

1 Ответ

0 голосов
/ 25 октября 2018

Тот факт, что ваши классы являются абстрактными, совершенно не имеет значения.Если вы делаете их абстрактными, чтобы предотвратить их создание, и используете наследование, чтобы не указывать имя класса, тогда это антипаттерн, который не использует абстрактные классы для полиморфизма, поскольку они предназначены для использования.Просто добавьте приватный конструктор в классы и используйте статический импорт.

Теперь, что касается самого вопроса, вам нужно сделать метод универсальным, а метод MyConverter.convertObjectToType() - также:

public static <T> List<T> myMethod(Class<T> clazz, MyConverter converter, List<Object> objects) {
    return objects.stream()
              .map(object -> converter.convertObjectToType(object, clazz))
              .collect(Collectors.toList());
}
...