public class CSVParser {
protected <T extends Message> void addMessageToResult(Message message, Descriptor descriptor, ImmutableList.Builder<T> messageListBuilder) {
. . .
}
對于 DynamicMessage 我想有不同的處理,所以我嘗試了
public class CSVParserDynamicMessage extends CSVParser {
protected<DynamicMessage> void addMessageToResult(Message message, Descriptor descriptor, ImmutableList.Builder<DynamicMessage> messageListBuilder) {
messageListBuilder.add(DynamicMessage.parseFrom(descriptor, message.toByteString()));
}
但它給出了編譯錯誤
'com.google.cloud.verticals.telco.taap.dataflow.dataingestion.common.parsers.CSVParserDynamicMessage' 中的 'addMessageToResult(Message, Descriptor, Builder)' 與 'com. google.cloud.verticals.telco.taap.dataflow.dataingestion.common.parsers.CSVParser'; 兩種方法都有相同的擦除,但都沒有覆寫另一個
我不得不做下面丑陋的方法(還沒有嘗試運行,看看它是否真的有效):
@Override
protected<T extends Message> void addMessageToResult(Message message, Descriptor descriptor, ImmutableList.Builder<T> messageListBuilder)
throws InvalidProtocolBufferException {
messageListBuilder.add((T) DynamicMessage.parseFrom(descriptor, message.toByteString()));
}
請注意,我的子類化嘗試受到Java 泛型(模板)專業化可能(用特定型別覆寫模板型別)的啟發,但不同之處似乎在于,在我的情況下,模板引數 T 不存在于類級別,而僅存在于方法級別. 我無法理解為什么它不適用于我的用例。
任何想法都非常感謝。
uj5u.com熱心網友回復:
更新
什么意思
T像, U, - 這樣的泛型型別引數R只是型別的占位符,而不是實際型別。按照約定,型別引數用單個字母表示,但多字符型別引數也可以編譯:
public <Something> void doIt(Something s) {}
Something編譯器不會將其視為類或介面名稱,它只是一個占位符。
protected <DynamicMessage> void addMessageToResult(Message message, Descriptor descriptor, ImmutableList.Builder<DynamicMessage> messageListBuilder) {}
以及DynamicMessage像T. 這意味著您已將超類中宣告的泛型型別引數更改為T extends Message任意T. 這是不正確的。
一開始我沒有發現你打算用非泛型方法覆寫泛型方法,那是行不通的。
原因是由于泛型型別擦除而T extends Message編譯。Object即您可能會想到它,因為在父類中宣告了一個帶有 type 引數的非泛型方法Object,因此無法通過提供DynamicMessageas type 而不是Object.
一個泛型方法只能被另一個泛型方法覆寫,泛型型別引數完全相同。
錯誤訊息中完整描述了該問題:由于泛型型別擦除,您不能有兩個具有相同名稱和僅通過泛型型別引數不同的引數的方法。
例如,這兩種方法會發生沖突(即它們的簽名將被視為相同):
public void doIt(List<Integer> list) {}
public void doIt(List<String> list) {}
因為在運行時,編譯器只會List<Object>添加一個安全的檢查轉換。
當我們需要兩種不同的方法時的補救措施:
- 方法簽名應該因方法名稱或引數集而不同(不考慮泛型型別引數)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494538.html
上一篇:上限通配符作為映射值-如何使用getOrDefault()提供默認值
下一篇:如何傳遞多個實作相同介面的型別?
