Java 8中的方法引用:是否支持重载?

5

有没有办法在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中,方法调用在编译时被绑定到特定的方法重载,因此也不存在动态绑定。 - Boris the Spider
糟糕!是的,我指的是重载,我已经修正了问题,谢谢。 - zakmck
1
确实无法获取方法引用,使其像指向重载方法一样运行。你能做的最好的事情就是添加另一个方法,比如 void foo(Object x),然后从中获取一个消费者,但它仍然总是调用该确切的方法(带有 Object 参数),永远不会解析为其他任何东西。 - M. Prokhorov
@MikhailProkhorov,正如我所写的,我不想编写那种包装器,因为我有许多不同的foos要调用 :-) 因此编写所有这些包装器会使反射更实用。 - zakmck
1个回答

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;

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

如果您愿意承担反射开销,可以使用

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)

当使用不支持的参数类型调用时,这当然会在运行时失败。


谢谢 @Holger。在实践中,这个在Java中是缺失的 :-) 我理解它是符合静态类型检查的,但还是不太好(接受任意对象,运行时绑定并在编译时发出警告对我来说更好)。关于反射,我正在使用org.apache.commons.lang3.reflect.MethodUtils,语法更简单。 - zakmck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接