我正在嘗試創建一個通用方法,它接受兩個型別化的引數,其中一個由自身限定,
class Foo
{
<T extends Foo, V> void myself(final Optional<V> value, final BiConsumer<T, V> destination)
{
if (value.isPresent())
{
destination.accept(~~this~~, value.get());
}
}
}
但是編譯器歸咎于這個this論點,因為
error: incompatible types: Foo cannot be converted to T
destination.accept(this, value.get());
^
where T,V are type-variables:
T extends Foo declared in method <T,V>myself(Optional<V>,BiConsumer<T,V>)
V extends Object declared in method <T,V>myself(Optional<V>,BiConsumer<T,V>)
IfT是 的子型別Foo,我不明白為什么this(這是Foo肯定的)不能是T.
強制(T) this演員似乎“有效”。
更新
我想通過以下方式使用它,
class Bar extends Foo
{
void setAnswer(Integer toLife)
{
}
}
----
void outThere(Bar bar)
{
bar.myself(Optional.of(42), Bar::setAnswer);
}
通配符的提議
class Foo
{
<V> void myself(final Optional<V> value, final BiConsumer<? super Foo, V> destination)
{
if (value.isPresent())
{
destination.accept(this, value.get());
}
}
}
使用失敗,
error: incompatible types: invalid method reference
bar.myself(Optional.of(42), Bar::setAnswer);
^
method setAnswer in class Bar cannot be applied to given types
required: Integer
found: Foo,V
reason: actual and formal argument lists differ in length
where V is a type-variable:
V extends Object declared in method <V>myself(Optional<V>,BiConsumer<? super Foo,V>)
uj5u.com熱心網友回復:
T extends Foo
它有界的Foo,但它不一定是實際 Foo。它可以是Foo替代的任何子型別。
使用通配符代替定義型別變數:
final BiConsumer<? super Foo, V> destination
此外,撰寫方法主體的更好方法是:
value.ifPresent(consumer);
(與直接執行此操作相比,呼叫您的方法并沒有太大的優勢)。
更新您的更新:
如果要表達類似于 self 型別的內容,則需要向類中添加另一個型別變數:
class Foo<F extends Foo<F>>
{
<V> void myself(final Optional<V> value, final BiConsumer<? super F, V> destination) {
if (value.isPresent())
{
// (F) is an unchecked cast, but is necessary, because
// nothing constrains F to actually be "itself".
destination.accept((F) this, value.get());
}
}
然后Bar類定義為:
class Bar extends Foo<Bar> {
void setAnswer(Integer toLife) { /* ... */ }
}
然后該outThere方法作業正常:
void outThere(Bar bar)
{
bar.myself(Optional.of(42), Bar::setAnswer);
}
Ideone demo
uj5u.com熱心網友回復:
假設,Foo有兩個子類,Foo1并且Foo2,都沒有覆寫該myself()方法。然后:
Foo1 me = ...;
Optional<String> value = ...
BiConsumer<Foo2,String> consumer = ...;
me.myself(value, consumer);
火柴
<T extends Foo, V> void myself(final Optional<V> value, final BiConsumer<T, V> destination) {...}
與VbeingString和Tbeing Foo2, whilethis是 class Foo1,所以你不能把它傳遞給Foo2消費者。
這就是編譯器檢測到的。
uj5u.com熱心網友回復:
問題是,有沒有保證,你T是兼容this。
可能BiConsumer是指某個東西extends T,然后T不適合。問題是您正在推斷T并且可能與this.
如果你真的想要這個,那么你應該T一起洗掉所有內容并使用Foo.
如果您想要任何擴展Foo并希望推斷出它的東西,那么您可以super改用。
<V> void myself(final Optional<V> value, final BiConsumer<? super Foo, V> destination) {
if ( value.isPresent() ) {
destination.accept(this, value.get());
}
}
不過,您會發現這種方法存在一些問題。
否則,您也可以直接使用Foo如上所述:
public static class Foo {
<T, V> void myself(final Optional<V> value, final BiConsumer<Foo, V> destination) {
if ( value.isPresent() ) {
destination.accept(this, value.get());
}
}
}
否則,如果您真的確定可以投射它,但并不真正推薦這樣做。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/335834.html
上一篇:打字稿通用聯合決議順序
