我有很多相同的课程。我想用泛型来改进它:
public class PingInitializer extends AbstractHandler implements DataWarehouseInitializer<PingInteraction, PingInvocation> {
@Handler
@Override
public PingInteraction handle(Message message) throws IOException, MessageException {
checkMessageIsNotNull(message);
PingInvocation invocation = construct(message.getBody().toString());
l.debug("handling in initializer... {}", invocation);
return new PingInteraction(invocation);
}
public PingInvocation construct(String message) throws IOException, MessageException {
ObjectMapper mapper = new ObjectMapper();
PingInvocation invocation;
try {
invocation = mapper.readValue(message, PingInvocation.class);
} catch (IOException e) {
throw new MessageException("Can't deserialize message", e);
}
return invocation;
}
}
我想创建新的抽象类AbstractInitializer,所有子类只需要指定泛型类型:
public abstract class AbstractInitializer<INTERACTION, INVOCATION> extends AbstractHandler {
@Handler
public INTERACTION handle(Message message) throws IOException, MessageException {
checkMessageIsNotNull(message);
INVOCATION invocation = construct(message.getBody().toString());
l.debug("handling in initializer... {}", invocation);
return **new INTERACTION(invocation)**; //HERE!
}
public INVOCATION construct(String message) throws IOException, MessageException {
ObjectMapper mapper = new ObjectMapper();
INVOCATION invocation;
try {
invocation = mapper.readValue(message, **INVOCATION.class** /*<- and HERE */);
} catch (IOException e) {
throw new MessageException("Can't deserialize message", e);
}
return invocation;
}
}
但我有两个编译器错误,不知道如何绕过这个问题。我在代码中标记它们
答案 0 :(得分:2)
出于兼容性原因,使用类型擦除实现Java泛型,这最终意味着您不能使用纯粹的类型参数来实例化新对象。
您需要修改AbstractInitializer
一点......
private final Class<INTERACTION> interactionType;
private final Class<INVOCATION> invocationType;
private final Constructor<INTERACTION> interactionConstructor;
public AbstractInitializer(final Class<INTERACTION> interactionType,
final Class<INVOCATION> invocationType) throws NoSuchMethodException {
this.interactionType = interactionType;
this.invocationType = invocationType;
interactionConstructor = interactionType.getConstructor(invocationType);
}
public INTERACTION handle(Message message) throws IOException, MessageException,
InvocationTargetException, InstantiationException, IllegalAccessException {
checkMessageIsNotNull(message);
INVOCATION invocation = construct(message.getBody().toString());
l.debug("handling in initializer... {}", invocation);
return interactionConstructor.newInstance(invocation);
}
public INVOCATION construct(String message) throws IOException, MessageException {
ObjectMapper mapper = new ObjectMapper();
INVOCATION invocation;
try {
invocation = mapper.readValue(message, invocationType);
} catch (IOException e) {
throw new MessageException("Can't deserialize message", e);
}
return invocation;
}
然后,作为一个例如。
public final class PingInitializer
extends AbstractInitializer<PingInteraction, PingInvocation> {
public PingInitializer() {
super(PingInteraction.class, PingInvocation.class);
}
}
或者,你可以放弃它abstract
并像......一样使用它。
public static GenericInitializer<A, B> createInitializer(final Class<A> a,
final Class<B> b) {
return new GenericInitializer<A, B>(a, b);
}
final GenericInitializer<PingInteraction, PingInvocation> pingInitializer
= createInitializer(PingInteraction.class, PingInvocation.class);
我相信这应该是可能的。我可能会犯一些愚蠢的错误,因为我在响应框中匆匆输入了这个。