首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无效方法引用/模糊引用(javac / ecj行为差异)

无效方法引用/模糊引用(javac / ecj行为差异)
EN

Stack Overflow用户
提问于 2015-11-10 00:52:08
回答 1查看 724关注 0票数 2

当使用时,以下代码将正确编译和运行。

代码语言:javascript
复制
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 );
        }

    }
}

..。

代码语言:javascript
复制
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编译时,会发出以下错误:

代码语言:javascript
复制
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(...)方法。T型或无效型)

总的问题是“为什么会有行为差异?”,但也许可以细分为:

  • javac是对方法引用限制太严格了,还是Eclipse编译器在这里不够严格?
  • javac是否正确地确定方法解析是不明确的,还是仅仅缺乏Eclipse编译器的智慧来正确地确定应该选择哪一种方法?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-10 04:11:49

这是javac编译器(参见JDK-8139836)中的一个已知错误,最终在OpenJDK 1.9ea-b89中修复。您可以下载Java9早期访问构建并看到它正常编译您的代码。此错误仅影响方法引用。您可以用lambda表达式替换它。它不会太长,并且在ECJ和javac中都编译得很好:

代码语言:javascript
复制
return (Foo)uncheck( () -> super.clone() );
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33621060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档