간단한 생성자에 인수로 파서를 전달하는 것입니다 :
public abstract class ProtoDeserializer<T extends Message> {
private final Parser<T> parser;
public ProtoDeserializer(Parser<T> parser) {
this.parser = parser;
}
public T deserialize(final byte[] bytes) throws Exception {
T message = parser.parseFrom(bytes);
validate(message);
return message;
}
public abstract void validate(final T message) throws Exception;
}
파서를 전달하는 것이 나의 현재의 해결 방법입니다. 그러나 중복 된 정보이기 때문에 그것을 피하는 것이 좋을 것입니다.
중복 될 수 있지만 컴파일러/런타임에는 중복되지 않습니다.
당신이 클래스의 원시 구현을 만들 수 있음을 고려하는 경우 : T
이 곳에서 온 것
ProtoDeserializer proto = new ProtoDeserializer() {
...
};
유형입니다.
이것은 지워진 제네릭의 현실입니다. generic 매개 변수의 유형 정보가 필요하면 수동으로 제공해야합니다.
이
private final Parser<T> parser;
public ProtoDeserializer() {
Class<?> subclass = this.getClass();
try {
ParameterizedType pType = (ParameterizedType) subclass.getGenericSuperclass();
Class<T> tClass = (Class<T>) pType.getActualTypeArguments()[0];
// In the case where the constructor for `T` takes no arguments.
parser = tClass.newInstance().getParserForType();
} catch(Throwable t) {
throw new RuntimeException("Subclass not compatible", t);
}
}
이만큼 서브 클래스가 직접 구체적인 형식 인수와 ProtoDeserializer
구현으로 작동합니다 :
또 다른
당신이 시도 할 수이 구현 서브 클래스에서 구체적인 형식 매개 변수를 얻는 것입니다 해킹 . ie :
class MyDeserializer extends ProtoDeserializer<MyMessage> {...}
현재 해결 방법은 구문 분석기를 생성자 인수로 전달하는 것입니다. 그러나 중복 된 정보이기 때문에 그것을 피하는 것이 좋을 것입니다. – maja
'getParserForType'이'static'이 아닌지 물어볼 수도 있습니다. 어떻게 호출합니까? 'T'를 인스턴스화합니까? –
@ JornVernee 위의 코드에서 구문 오류입니다. 실제로 작동하지 않습니다. 그것은 그것이 작동하기를 기대하는 방법의 예입니다. – maja