父类想获取子类上的泛型,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public abstract class AbsFileHandle<T> { public void start(String filepath){ } protected abstract void preview(T t); }
public class File1Handle extends AbsFileHandle<DemoFile1>{ @Override protected void preview(DemoFile1 demoFile1) {
} }
public class DemoFile1 { }
|
解决办法有多种:
- 写个抽象方法,返回具体类型
- 写个构造方法,参数是具体类型
- 通过反射获取
采用反射获取如下
1 2 3 4 5 6
| public AbsFileHandle() { Type type = this.getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) type).getActualTypeArguments(); childClazz = (Class<T>) params[0]; }
|
上面代码就可以获取到子类的泛型。
Spring泛型消息处理
在Spring中如果需要监听消息,消息又是泛型时,因为泛型擦除导致不符合预期。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class BaseEvent<T>extends ApplicationEvent { private T data; private int times;
public BaseEvent(T source) { super(source); } public void handle(){ times += 1; }
public int getTimes() { return times; }
public T getData() { return data; } }
@EventListener public void listener(BaseEvent<String> event) { event.handle(); } @EventListener public void listener2(BaseEvent<Integer> event) { event.handle(); }
@SpringBootTest(classes = Application.class) public class EventTest { @Autowired private ApplicationContext context; @Test public void event(){ BaseEvent<String> event1 = new BaseEvent<>("123"); context.publishEvent(event1); assertEquals(event1.getTimes(), 1); BaseEvent<Integer> event2 = new BaseEvent<>(123); context.publishEvent(event2); assertEquals(event1.getTimes(), 1); } }
|
上述消息测试中,发送消息后,会被处理2次,也就是两个消息监听器都做了处理。
如果需要对应泛型指处理一次,需要改进如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class BaseEvent<T>extends ApplicationEvent implements ResolvableTypeProvider { private T data; private int times;
public BaseEvent(T source) { super(source); } public void handle(){ times += 1; }
public int getTimes() { return times; }
public T getData() { return data; }
@Override public ResolvableType getResolvableType() { return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getSource())); } }
|
实现ResolvableTypeProvider接口。原理应该是消息监听推送时如果是ResolvableTypeProvider子类,那就调用方法获取对应泛型类型。
参考:
context-functionality-events-generics