Java 的 record equals() 方法实际上是做什么的?

问题描述 投票:0回答:1

在我的 Java 代码中,我有一个简单的记录类,如下所示:

record SingleIndexProperties<A>(A property) implements IndexProperties {

    // Here go implementations of IndexProperties methods; not relevant to question.

}

当我使用此记录运行代码的 JMH 基准测试时,我注意到最后生成的 CPU 时间火焰图中有一些有趣的东西:

java equals record
1个回答
0
投票

请看一下jdk内部的ObjectMethods类,特别是bootstrap和makeEquals方法。

private static MethodHandle makeEquals(Class<?> receiverClass,
                                      List<MethodHandle> getters) {
    MethodType rr = MethodType.methodType(boolean.class, receiverClass, receiverClass);
    MethodType ro = MethodType.methodType(boolean.class, receiverClass, Object.class);
    MethodHandle instanceFalse = MethodHandles.dropArguments(FALSE, 0, receiverClass, Object.class); // (RO)Z
    MethodHandle instanceTrue = MethodHandles.dropArguments(TRUE, 0, receiverClass, Object.class); // (RO)Z
    MethodHandle isSameObject = OBJECT_EQ.asType(ro); // (RO)Z
    MethodHandle isInstance = MethodHandles.dropArguments(CLASS_IS_INSTANCE.bindTo(receiverClass), 0, receiverClass); // (RO)Z
    MethodHandle accumulator = MethodHandles.dropArguments(TRUE, 0, receiverClass, receiverClass); // (RR)Z

    for (MethodHandle getter : getters) {
        MethodHandle equalator = equalator(getter.type().returnType()); // (TT)Z
        MethodHandle thisFieldEqual = MethodHandles.filterArguments(equalator, 0, getter, getter); // (RR)Z
        accumulator = MethodHandles.guardWithTest(thisFieldEqual, accumulator, instanceFalse.asType(rr));
    }

    return MethodHandles.guardWithTest(isSameObject,
                                       instanceTrue,
                                       MethodHandles.guardWithTest(isInstance, accumulator.asType(ro), instanceFalse));
}

似乎jdk的当前实现会生成equals作为invokedynamic调用,这又会调用方法句柄组合上的许多递归调用。我希望记录类生成字节码 equals/hashcode (无论是在编译期间还是运行时),但在当前版本中似乎不是这种情况。 (当前是指截至撰写本文时的 JDK 21 和 23)

这显然对性能造成了影响。正如其他人所提到的,考虑到应用程序中其他所有内容的成本,它不太可能影响现实生活中的任何人,但如果您的分析显示了这一点,那么针对少数瓶颈类手动实现它可能是一个好主意。

© www.soinside.com 2019 - 2024. All rights reserved.