[英]Java 8 Method Reference to non-static method
為什么這不起作用? 我得到編譯錯誤“無法對非靜態方法打印靜態引用...”
public class Chapter3 {
public void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
Arrays.asList("a", "b", "c").forEach(Chapter3::print);
}
}
無論您是使用方法引用,lambda表達式還是普通方法調用,實例方法都需要適當的實例來進行調用。 該實例可以由函數調用提供,例如,如果forEach
期望BiConsumer<Chapter3,String>
它工作。 但是因為forEach
在你的情況下期望一個Consumer<String>
,所以在范圍內沒有第Chapter3
實例。 您可以通過將Chapter3.print
更改為static
方法或通過提供實例作為方法調用的目標來輕松解決此問題:
public class Chapter3 {
public void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
Arrays.asList("a", "b", "c").forEach(new Chapter3()::print);
}
}
在此,結果new Chapter3()
的新實例Chapter3
,將被捕獲的方法參考其print
方法及Consumer<String>
調用該實例上的方法,可以構建。
forEach
接受Consumer<? super T>
Consumer<? super T>
(它的簽名是default void forEach(Consumer<? super T> action)
),這是一個帶有一個參數accept(T t)
的函數接口。
當你傳遞有一個參數的方法的非靜態方法的參考,你實際上有兩個參數-在this
參照Chapter3
實例和字符串參數。 這與forEach
期望的不匹配。
我想我現在明白了。 Stream中的內容是String類型因此我不能在String intance上調用print ...
例如,這是有效的
public class Chapter3 {
final String value;
public Chapter3(String value) {
this.value = value;
}
public void print() {
System.out.println(value);
}
public static void main(String[] args) {
Arrays.asList(new Chapter3("a"), new Chapter3("b")).forEach(Chapter3::print);
}
}
以防您是否嘗試從運行代碼的同一對象應用實例方法
Arrays.asList("a", "b", "c").forEach(this::print);
如果您不匹配函數的類型和從中生成函數的對象,您將看到非靜態錯誤。 例如,這行代碼將無法編譯,因為函數需要將Foo作為它所處理的類型,但該函數適用於Foobar:
Function<Foo, Bar> func = Foobar::getBar;
它不僅處理它在for循環或任何其他參數中的時間,也不處理“范圍內的內容”。 這是一個類型不匹配錯誤,java在使用新函數對象時貼錯標簽。 將此與構造其他泛型時發生的情況進行比較:
List<Foo> list = new ArrayList<Bar>();
該行代碼將無法使用錯誤“不兼容的類型”進行編譯。 更好的是,盡管以幾乎完全相同的方式處理功能對象,此代碼也會因不兼容的類型而失敗:
public void test() {
Function<Foo, Double> test2 = Foo::getDouble;
//fails with Incompatible types
test3(test2);
}
public void test3(Function<Foobar, Double> function) {
//who cares
}
我最好的建議是當你開始出現這個錯誤時,將函數聲明拉出到一個新行,你應該能夠看到實際問題是什么。 為什么java選擇“非靜態方法無法從靜態上下文引用”超出了我的范圍。
您可以使您的print
功能保持static
,這樣您就不需要實例來調用它:
public class Chapter3 {
public static void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
Arrays.asList("a", "b", "c").forEach(Chapter3::print);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.