2017-09-15 219 views
2

在Java中,給定一個非靜態方法引用和一個類的實例,有可能以某種方式傳達您希望該類實例調用該方法嗎?在實例參數中調用實例方法參考

僞例如:

public Object methodApply(Function<Object,Object> method, Object instance, List<Object> args) { 
    return instance.method(args); 
} 
+2

'功能'沒有意義,因爲它需要輸入類型和輸出類型。你可能在尋找反思? –

+0

@JoeC好抓!編輯修復 –

回答

3

你不能聲明調用任何任何類中聲明的對象上的方法,但是如果你使用reflection
反射方法的缺點是,如果方法/訪問無效,您可能會在運行時遇到異常。

利用Java 8,可以通過任何method reference實現一個功能接口(它是如此只是替代lambda表達式)。
限制是這個方法的引用必須符合功能接口描述符。


如果你真的要使用Java 8和類型安全中受益,以實現你的需要,你應該充分利用,你可以在一個變量,不會使拉姆達的一部分調用方法的引用。
但請注意,函數接口接受的參數個數不可變。
所以你應該這樣重載你的泛型方法來接受不同數量的參數。

例如,如果你想要一個參數傳遞給調用的方法,methodApply()應該有一個Function<T,R>參數:

public static <T, R> R methodApply(Function<T, R> function, T arg) { 
    return function.apply(arg); 
} 

但是,如果你也想對能夠在兩個參數傳遞給調用的方法, methodApply()應該過載,有這麼一個BiFunction<T, U, R>參數:

public static <T, U, R> R methodApply(BiFunction<T, U, R> function, T argOne, U argTwo) { 
    return function.apply(argOne, argTwo); 
} 

如果您需要更多參數傳遞,你當然可以創建自己的樂趣標準接口:TriFunction,QuadriFunction並以相同方式重載該方法。

下面是一個示例工作代碼示出的是:

import java.util.ArrayList; 
import java.util.List; 
import java.util.function.BiFunction; 
import java.util.function.Function; 

public class FunctionHelper { 

    public static void main(String[] args) { 

     System.out.println("methodApply() with Function" + System.lineSeparator()); 
     // String.concat 
     String oneString = "hello"; 
     String concatenated = methodApply(oneString::concat, " world"); 
     System.out.println("concatenated="+ concatenated); 

     // List add/remove 
     List<String> list = new ArrayList<>(); 
     methodApply(list::add, concatenated); 
     System.out.println("after adding, list="+list); 
     methodApply(list::remove, concatenated); 
     System.out.println("afer removing, list="+list); 

     System.out.println("---------------------------"+ System.lineSeparator()); 

     System.out.println("methodApply() with BiFunction" + System.lineSeparator()); 
     // String.substring 
     oneString = "hello world";  
     System.out.println("substring=" + methodApply(oneString::substring, 0, 6)); 
    } 

    public static <T, R> R methodApply(Function<T, R> function, T arg) { 
     return function.apply(arg); 
    } 

    public static <T, U, R> R methodApply(BiFunction<T, U, R> function, T argOne, U argTwo) { 
     return function.apply(argOne, argTwo); 
    } 

} 

輸出:

methodApply()帶有功能

級聯=世界你好

添加後,列表= [你好世界]

AFER除去,列表= []


methodApply()與雙功能

子=你好