LINUX.ORG.RU

Switch generics cast Java.

 


0

2

Есть interface Message<T>.

Есть ObjectInputStream.

Я хочу узнать, пришло ли мне через ObjectInputStream Message<String> или какая-то иная шняга, вроде UpdateRequest. Как это проверить?

Сейчас я делаю это так:

Object incomingObject = objectInputStream.readObject();

if (incomingObject instanceOf Message) {
    Message<String> message = (Message<String) incomingObject;
    ...
} else {
    ...
}
но это же хрень, а не решение. Как правильно проверить, что это именно Message<String> а не просто Message?

Deleted

Не уверен, что правильно понял вопрос, но, скорее всего, никак, ибо Type Erasure (https://docs.oracle.com/javase/tutorial/java/generics/erasure.html).

Т.е. в рантайме у тебя никаких generics не будет, будет тупо Message.
Если же хочешь проверять просто класс ли это Message или нет, то instanceof здесь прекрасно подходит.

Вообще, какая тебе разница, какой там дженерик был? Ты проверил, что объект является Message - вот и работай дальше с ним как с Message.
Если это что-то другое - то иди в другую бранчу и обрабатывай по-другому.

Если же у тебя принципиально разные обработчики разных Message'в, тогда сделай либо:
1) общий интерфейс (IMessage какой-нибудь) + разные имплементации. И в рантайме вызывай общие интерфейсные методы. А дальше полиморфизм сам пусть все делает.

2) общий абстрактный класс (хотя, с появлением default methods тебе может уже и интерфейса хватит), а от него наследуй различные подклассы.

kovrik ★★★★★
()

Я бы написал что-то примерно такое:

public class Main {
    
    interface Message<T> {
        <V> Message<V> cast(Class<V> genericParameterClass);
        
        T getFoo();
    }
    
    static abstract class BaseMessage<T> implements Message<T> {
        
        private final Class<T> genericParameterClass;
        
        public BaseMessage(Class<T> genericParameterClass) {
            this.genericParameterClass = genericParameterClass;
        }

        @Override
        public <V> Message<V> cast(Class<V> genericParameterClass) {
            if (this.genericParameterClass != genericParameterClass)
                return null;
            
            return (Message<V>) this;
        }
    }
    
    static class MessageImpl extends BaseMessage<String> {
        public MessageImpl() {
            super(String.class);
        }

        public String getFoo() {
            return "Foo";
        }
    }

    public static void main(String[] args) {
        Message<?> message = new MessageImpl();
        
        Message<String> stringMessage = message.cast(String.class);
    }
}
com
()
Ответ на: комментарий от unt1tled

Важна не скорость, а сортировка задач по типу приходящего сообщения.

Deleted
()
Ответ на: комментарий от Legioner

Спасибо. Моё решение было примерно таким же.

Deleted
()
Ответ на: комментарий от kovrik

Вообще, какая тебе разница, какой там дженерик был? Ты проверил, что объект является Message - вот и работай дальше с ним как с Message.

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

loz ★★★★★
()
Ответ на: комментарий от loz

Лол, жду от тебя пример кода на джава, где ты не подстраиваешься под ограничения джавовских дженериков, а решаешь свою детскую проблему.

kovrik ★★★★★
()

Class<T> Message.getType()

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.