Всем привет. Застрял в одном месте, никак не знаю как решить проблему.
Общая суть.
Есть иерархия классов.
public abstract class A {
}
public class B extends A {
}
public class C extends A {
}
Собственно с какой-то реализацией, но это не важно, также использую Google пакет guava и eventBus.
Соствеено хочу написать дистпатчер, но чтобы он принемал события дженериками
Класс события.
public class CreateEvent<T extends A> {
}
Дистпатчер
public class Test {
public void createEntity(CreateEvent<T extends A>) {
//Создать объект определенного класса
}
}
Никак не могу понять, как мне узнать для какого класса было вызввано событие и создать его, думал о том чтобы в событии содержать новый объект при создании, но как-то не красиво. Подскажите пожалуйста, куда копать, как узнать какой класс в событии чтобы создать объект этого класса.
Спасибо
Re: Generic EventDispatcher
От:
Аноним
Дата:
19.05.12 21:46
Оценка:
Может быть, я иду не верным путем и так никто не делает? Не нужно широких ответов, просто куда копать и где посмотреть, либо может на какой нить класс в исходниках? Спасибо.
Здравствуйте, Аноним, Вы писали:
А>Соствеено хочу написать дистпатчер, но чтобы он принемал события дженериками
В общем случае узнать тип генерик-параметра нельзя из-за type erasure. Конкретно в вашем случае можно использовать
Class<? extends A> realClass = ((ParameterizedType)event.getClass().getGenericSuperclass()).getActualTypeArguments()[0]
Но лично я бы не назвал такое решение хорошим.
Re[2]: Generic EventDispatcher
От:
Аноним
Дата:
20.05.12 08:00
Оценка:
Здравствуйте.
Тогда какое хорошее решение, для того чтобы отправлять сообщение на создание объекта. Я думал, как вариант при создании события, создавать и сам объект с конструктором по умолчанию, но как то не очень хочется создавать объект до того как событие будет выполняться.
2 вариант, для событий "создать" не использовать генерик, а создавать отдельные классы событий, но так растет и кол-во классов.
3 вариант, при создании события, указывать тип объекта в каком-нибудь поле, опять же выкидываем генерик для данного класса события.
В других случаях, выгрыш с использованием генерика заметен, это события открытия и сохранения, когда событие содержит в себе объекта класса.
Здравствуйте, RomikT, Вы писали:
RT>Здравствуйте, Аноним, Вы писали:
А>>Соствеено хочу написать дистпатчер, но чтобы он принемал события дженериками
RT>В общем случае узнать тип генерик-параметра нельзя из-за type erasure. Конкретно в вашем случае можно использовать RT>
Class<? extends A> realClass = ((ParameterizedType)event.getClass().getGenericSuperclass()).getActualTypeArguments()[0]
public class CreateEvent<T extends A> {
private Class<T> targetType;
public CreateEvent(Class<T> targetType) {
this.targetType = targetType;
}
public Class<T> getTargetType() {
return targetType;
}
}
public class Test {
public void createEntity(CreateEvent<T extends A> event) {
try {
T instance = event.getTargetType().newInstance();
} catch (Exception e) {
// TODO
}
}
}
Re[2]: Generic EventDispatcher
От:
Аноним
Дата:
20.05.12 08:18
Оценка:
Здравствуйте, видел такое решение, является ли оно "хорошем" в данном случае, так теперь, у меня еще может появится exception, плюс создание сорбытия будет таким CreateEvent<B>(B.class);
Здравствуйте, Baudolino, Вы писали:
B>
B>public class CreateEvent<T extends A> {
B> private Class<T> targetType;
B> public CreateEvent(Class<T> targetType) {
B> this.targetType = targetType;
B> }
B> public Class<T> getTargetType() {
B> return targetType;
B> }
B>}
B>public class Test {
B> public void createEntity(CreateEvent<T extends A> event) {
B> try {
B> T instance = event.getTargetType().newInstance();
B> } catch (Exception e) {
B> // TODO
B> }
B> }
B>}
B>
class CreateEvent<T extends A> { // или интерфейс.
T create();
}
class Sender {
public void send(){
eventSender.send(new CreateEvent<B>(){ // или эту фабричность в мемберы класса, если параметров создания нет.
@Override
public B create() {
return new B();
}
});
eventSender.send(new CreateEvent<C>(){ // see above
@Override
public C create() {
return new C();
}
});
}
}
class Receiver{
<T extends A> void onMessage(CreateEvent<T> event) {
T t = event.create();
//...
}
}
А>Здравствуйте, видел такое решение, является ли оно "хорошем" в данном случае, так теперь, у меня еще может появится exception, плюс создание сорбытия будет таким CreateEvent<B>(B.class);
Решение является хорошим, если оно решает вашу задачу, и плохим, если оно задачу не решает. Более того, в большинстве случаев решение напрямую следует из формулировки задачи, и если вас что-то не устраивает в предлагаемых решениях, значит вы недостаточно хорошо сформулировали задачу. Простой вопрос: почему вас беспокоит исключение? Вопрос посложнее: а зачем вам вообще создавать объекты таким образом? Какую задачу вы в действительности решаете?
Re[4]: Generic EventDispatcher
От:
Аноним
Дата:
23.05.12 08:14
Оценка:
А>>Здравствуйте, видел такое решение, является ли оно "хорошем" в данном случае, так теперь, у меня еще может появится exception, плюс создание сорбытия будет таким CreateEvent<B>(B.class); B>Решение является хорошим, если оно решает вашу задачу, и плохим, если оно задачу не решает.
Если решение не решает задачу — оно не плохое, а некорректное. Строго говоря — это не решение.
B>Более того, в большинстве случаев решение напрямую следует из формулировки задачи, и если вас что-то не устраивает в предлагаемых решениях, значит вы недостаточно хорошо сформулировали задачу.
Ты виноват, что не сказал, ты виноват, что не спросил. Что за детский сад?