Java 8或Java 11-我通过枚举构造函数加载静态函数接口.然后,我try 与相同的成员引用进行比较.要么代码无法编译,要么与相同函数接口的比较失败.使用.equals和==进行比较以及使用.hashcode()进行比较都会失败.我已经创建了下面的POJO测试,它演示了这个问题并指出了相关的特定点.我想编写代码"如果实例成员等于specific-static-functional-interface-method-x,,则执行..."

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import java.util.function.Function;

import org.junit.jupiter.api.Test;

enum MethodReferenceEnum {
    One("One", MethodReferenceInterface::one),
    Two("Two", MethodReferenceInterface::two);

    public String name;
    public Function<String, Integer> method;

    private MethodReferenceEnum(String aName, Function<String, Integer> aMethod) {
        name = aName;
        method = aMethod;
    }
}

interface MethodReferenceInterface {
    public static Integer one(String aString) {
        return 1;
    }
    public static Integer two(String aString) {
        return 2;
    }
}

class MethodRererencesTest {

    @Test
    void LocalUseTest() {
        // This performs in JavaSE-8 (jdk-1.8.0_271) and JavaSE-11 (jdk-11.0.11).

        // These succeed in placing the member references in variables.
        Function<String, Integer> choice1a = MethodReferenceInterface::one;
        Function<String, Integer> choice1b = MethodReferenceEnum.One.method;
        Function<String, Integer> choice2a = MethodReferenceInterface::two;

        // These succeed in executing the member references from variables.
        assertEquals(1, choice1a.apply("A").intValue());
        assertEquals(1, choice1b.apply("B").intValue());
        assertEquals(2, choice2a.apply("2nd").intValue());

        // Why does the following fail to compile?
        //
        // assertEquals(choice1a, MethodReferenceInterface::one);
        //
        // ^ assertEquals fails to compile due to:
        // The method assertEquals(Object, Object) in the type Assert is not applicable
        // for the arguments (Function<String, Integer), MethodReferenceInterface::one)
        // ^ MethodReferenceInterface::one fails to compile due to:
        // The target type of the expression must be a functional interface

        // Compiles and succeeds; expected.
        assertEquals(choice1a, choice1a);

        // This compiles, and succeeds,
        // but why do they not compare equal?
        assertNotEquals(choice1a, choice1b);
    }
}

最后一行和问题总结了这个问题.我在上面运行了测试,它通过了.问题在于,包含相同成员引用的变量在比较时并不相等.这发生在Java 8和Java 11中.

推荐答案

当您键入时:

Function<String, Integer> choice1a  = MethodReferenceInterface::one

编译器将其转换为:

Function<String, Integer> choice1a = new Function<>() {
   String apply(Integer n) {
     return 1;
   }
}

它知道将其转换为Function接口,而不知道由于成员choice1a的类型而不进行任何其他转换.

函数assertEquals不是通用函数,并且其输入是 object,object.因此,编译器不知道如何创建MethodReferenceInterface::one.

函数choice1a的第一个参数没有使函数泛型等于(又名assertEquals(Function, Function)),但它使函数泛型等于 assertEquals(object, object).

//编译成功后, //但为什么它们不能相提并论呢? AssertNotEquals(Choice1a、Choice1b);

它们并不等同于我最初所说的原因.每次使用::快捷方式时,都会在幕后创建一个新实例,并且它们的引用是不同的.

Java相关问答推荐

编译期间错误(Java 0000)Android .Net MAUI

更新我们的一个文物后出现了严重的符号引用错误

如果给定层次 struct 级别,如何从其预序穿越构造n元树

JPackaged应用程序启动MSI调试,然后启动System. exit()

Java事件系统通用转换为有界通配符

Cucumber TestNG Assert失败,出现java. lang. Numbercycle异常

使用java访问具体子类特定方法的最佳方法是什么?

Java inline Double条件和值解装箱崩溃

滚动视图&不能在alert 对话框中工作(&Q;&Q;)

如何判断一个矩阵是否为有框矩阵?

如何在EXCEL单元格中添加形状和文本

使用Jolt将字段转换为列表

为什么有两种实现来检索数组类的组件类型?

如何使用Criteria Builder处理一对多关系中的空值?

Java组件项目中的JavaFX对话框国际化

找出承载Cargo 的最小成本

从泛型枚举创建EnumMap

为什么mvn编译生命周期阶段不只是编译已更改的java文件?

在Java中将对象&转换为&q;HashMap(&Q)

在外部类和内部类之间,当调用外部类内部或外部的主方法时,它们的静态初始化程序的运行顺序不同