使用Eclipse Compiler for Java时,以下代码可以正确编译和运行。
package org.sandbox;
public final class ExceptionUtils
{
private ExceptionUtils(){}
@FunctionalInterface
public interface Runnable
{
void run() throws Exception;
}
@FunctionalInterface
public interface Callable<T>
{
T call() throws Exception;
}
public static void uncheck( final Runnable r )
{
try
{
r.run();
}
catch( final Exception e )
{
throw new RuntimeException( e );
}
}
public static <T> T uncheck( final Callable<T> c )
{
try
{
return c.call();
}
catch( final Exception e )
{
throw new RuntimeException( e );
}
}
}
...
package org.sandbox;
import static org.sandbox.ExceptionUtils.uncheck;
public class Foo
{
private String bar;
public String getBar()
{
return bar;
}
public void setBar( final String bar )
{
this.bar = bar;
}
@Override
public Foo clone()
{
return (Foo)uncheck( super::clone );
}
}
使用javac编译时,会发出以下错误:
org\sandbox\Foo.java:22: error: reference to uncheck is ambiguous
return (Foo)uncheck( super::clone );
^
both method <T>uncheck(Callable<T>) in ExceptionUtils and method uncheck(Runnable) in ExceptionUtils match
where T is a type-variable:
T extends Object declared in method <T>uncheck(Callable<T>)
org\sandbox\Foo.java:22: error: incompatible types: cannot infer type-variable(s) T
return (Foo)uncheck( super::clone );
^
(argument mismatch; invalid method reference
clone() has protected access in Object)
where T is a type-variable:
T extends Object declared in method <T>uncheck(Callable<T>)
2 errors
这里似乎有两个问题
uncheck(...)
方法是不可能的。整体问题是&#34;为什么会出现行为差异?&#34;,但也许可以分解为:
答案 0 :(得分:4)
这是javac编译器中的已知错误(请参阅JDK-8139836),最终在OpenJDK 1.9ea-b89中修复。您可以下载Java9 early access build并查看它是否正常编译代码。此错误仅影响方法引用。您可以用lambda表达式替换它。在ECJ和javac中,它的编写时间不长,编译得很好:
return (Foo)uncheck( () -> super.clone() );