Создание параметризованного текстового объекта с помощью анонимного класса

Это могло бы быть глупым вопросом, но я просто видел вопрос спросить, как создать Переменную типа для универсального типа. Согласие, казалось, было, что Вы должны иметь фиктивный метод, возвращая тот тип и затем использовать отражение для получения его (в этом случае, он хотел Map). Что-то вроде этого:

public Map dummy() { throw new Error(); }

Type mapStringString = Class.forName("ThisClass").getMethod("dummy").getGenericReturnType();

Мой вопрос, не используя отражение так очень, не могли Вы просто сделать что-то как:

Type mapStringString = new ParameterizedType() {
    public Type getRawType() {
        return Map.class;
    }

    public Type getOwnerType() {
        return null;
    }

    public Type[] getActualTypeArguments() {
        return new Type[] { String.class, String.class };
    }
};

Это работало бы? В противном случае, почему нет? И что является некоторыми опасностями/проблемами, если это делает (помимо способности возвратить некоторый Тип как Integer который, очевидно, не возможен.

11
задан Community 23 May 2017 в 12:32
поделиться

2 ответа

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

Однако, используя первый метод, вы получаете более изысканный объект. Скажем, например, что вы создаете объект type1 , используя первый метод, и type2 , используя второй метод. Тогда type1.equals (type2) вернет true (поскольку первый метод возвращает объект, который правильно реализует метод equals), но type2.equals (type1) вернет false (поскольку во втором методе вы не переопределили метод equals и используете реализацию из Object ).

Те же рассуждения применимы и к другим (иногда полезным методам), таким как toString , hashCode и т. Д. Второй метод не предоставляет их полезных реализаций.

7
ответ дан 3 December 2019 в 07:36
поделиться

На самом деле, я думаю, что самый простой способ (== минимум кода) сделать это - использовать фиктивный интерфейс, расширяющий интересующий вас тип, а затем getGenericInterfaces () [0] из его класса (используйте getGenericSuperclass () , если вас интересует класс):

private interface MapStringString extends Map<String, String> {}
private static ParameterizedType mapStringString(){
    return (ParameterizedType) MapStringString.class.getGenericInterfaces()[0];
}

Однако он плохо масштабируется, так как вам нужно создавать новый класс для каждого ParameterizedType , который вы хотите представлять. Я не понимаю, почему ваша реализация не годится (если где-то нет сужающих приведений), и у нее есть привлекательное преимущество, заключающееся в том, что вы можете сделать ее многоразовой.

2
ответ дан 3 December 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: