0

同じクラスがたくさんあります。ジェネリックを使用して改善したい:

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;
    }
}

しかし、2 つのコンパイラ エラーが発生し、この問題を回避する方法がわかりません。私はそれらをコードでマークします

4

1 に答える 1

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);

私はこれがすべて可能であるべきだと信じています。ただし、急いで応答ボックスにこれを入力したため、おそらくいくつかのばかげたエラーを犯した可能性があります。

于 2012-08-28T06:08:36.627 に答える