2017-02-01 51 views
2

有没有什么办法可以引用Java 8中的一组方法,这会改变它们的签名方式?Java 8中的方法引用:是否支持重载?

更确切地说,我想这个代码工作:

public class OverloadingMethodRef 
{ 
    public static void foo (int x) { 
     System.out.println ("An integer: " + x); 
    } 

    public static void foo (String x) { 
     System.out.println ("A String: " + x); 
    } 

    /** 
    * I want it to work without this 
    */ 
// public static void foo (Object x) { 
//  if (x instanceof Integer) foo ((int) x); else foo ((String) x); 
// } 

    public static void main (String[] args) 
    { 
     // Compile error, it wants a precise reference to one of them 
     Consumer<Object> c = PolymorphicMethodRef::foo; 
     foo ("bla"); // despite it could get it 
     foo (1); // and here too 
    } 
} 

我不能添加public static void foo (Object x),因为我有很多的方法来传递给另一个方法,我不想写包装。到目前为止,我只能通过反射(它可以接收param.getClass())来完成此操作,但我必须调用的方法具有不同的参数(> = 1),每次需要将它们放入数组中时,再将它们的类型放入另一个中。

+3

支持多态。也没有 - 这不是多态,这是**重载**。不,没有 - Java编程方法在编译时调用特定的方法重载。 –

+0

Whops!是的,我的意思是超载,我解决了这个问题,谢谢。 – zakmck

+1

确实不可能获得方法引用,就好像它指向重载方法一样。你可以做的最好的方法是添加另一种方法,如void foo(Object x),并让用户退出,但它仍然会始终调用该方法(使用Object参数),永远不会解析其他任何东西。 –

回答

5

方法引用支持使用与普通方法调用相同的规则进行重载。当你有一个Consumer<Object>,你可以通过任意Object情况下,其accept方法,即你可以写

Consumer<Object> c = /* some expression producing it*/; 
c.accept(new JButton()); 
// or just 
c.accept(new Object()); 

因为你不能写

foo(new JButton()); 
// or 
foo(new Object()); 

当你只有一个foo(int)foo(String),它也不可能写出

Consumer<Object> c = OverloadingMethodRef::foo; 

这将构建一个Consumer假装接受任意Object实例。

如果你愿意接受反射的开销,你可以使用

Consumer<Object> c=o -> { 
    try { 
     new Statement(OverloadingMethodRef.class, "foo", new Object[]{o}).execute(); 
    } catch (Exception ex) { 
     throw new RuntimeException(ex); 
    } 
}; 
c.accept(42); 
c.accept("bla"); 

(这是指java.beans.Statement

当然,这可以用一个不支持的参数被调用时,在运行时失败类型。

+0

谢谢@Holger。在实践中,这是从Java中缺少的:-)我知道它符合静态类型检查,但仍然不是很好(接受任意对象,在运行时绑定并在编译时提出警告对我来说会更好)。 Re:反射,我使用'org.apache.commons.lang3.reflect.MethodUtils',更简单的语法。 – zakmck