Guava TypeToken и общие классы

Я использую класс Guava TypeToken в своем проекте, но получаю неожиданный результат.

я имею MyGenericClass<T>:

public class MyGenericClass<T> implements MyInterface {

    private TypeToken<T> recordType;

    public MyGenericClass(String name) {
        this.recordType = new TypeToken<T>(getClass()) {};

        // ...
    }

    // ...

    @SuppressWarnings("unchecked")
    protected Class<T> getRecordType() {
        return (Class<T>) recordType.getRawType();
    }
}

Так что, если я создаю экземпляр объекта через new MyGenericClass<String>() а затем вызвать getRecordType() Я ожидаю получить java.lang.Stringвместо этого я получаю java.lang.Object,

Но если я расширю родовой класс:

public class MyStringImpl extends  MyGenericClass<String> {
    // ...
}

и создать экземпляр этого нового класса: new MyStringImpl() тогда я получаю правильный результат.

Почему это происходит? Это ожидаемое поведение TypeToken?

2 ответа

Решение

Чтобы сделать это, вам нужен тот же трюк анонимного подкласса, когда вы создаете экземпляр MyGenericClass:

new MyGenericClass<String>() {}

Если вы сделаете это, то вы получите String вернулся getRecordType, Причина, почему это необходимо, объясняется в JavaDocs для этого TypeToken конструктор

Клиенты создают пустой анонимный подкласс. Это позволяет встроить параметр типа в иерархию типов анонимного класса, чтобы мы могли восстановить его во время выполнения, несмотря на удаление.

Чтобы добавить некоторые скучные детали к ответу Яна: было бы хорошо, если TypeToken работал так, как вы ожидали, но это невозможно. Когда вы объявляете

public class MyGenericClass<T> implements MyInterface {...}

JVM видит что-то вроде

public class MyGenericClass<Object> implements MyInterface {...}

из-за стирания.

Но когда вы объявляете

public class MyStringImpl extends MyGenericClass<String> {...}

тогда в определении MyStringImpl используемые дженерики записываются и могут быть получены через Class#getGenericSuperclass(), Это (часть) магия позади TypeToken,

Другие вопросы по тегам