gpt4 book ai didi

scala - 反编译 Scala 代码 : why there are two overridden methods in the derived class?

转载 作者:行者123 更新时间:2023-12-04 06:31:08 25 4
gpt4 key购买 nike

反编译Scala代码:为什么派生类中有两个被覆盖的方法?

class A
{
private var str: String = "A"
val x: A = this

override def toString(): String = str

def m1(other: AnyRef): AnyRef = {
println("This is A.m1(AnyRef)")
other
}
}

class B extends A {
private var str: String = "B"
var z: Int = 0
override val x: B = this

override def m1(other: AnyRef): B = {
println("This is B.m1(AnyRef)")
this
}
}

上述代码的B类反编译为:
public class test$B extends test$A {
private java.lang.String str;
private int z;
private final test$B x;
private java.lang.String str();
private void str_$eq(java.lang.String);
public int z();
public void z_$eq(int);
public test$B x();
public test$B m1(java.lang.Object);
public java.lang.Object m1(java.lang.Object);
public test$A x();
public test$B();
}

我不明白为什么有两个“版本”的方法 m1在反编译的代码中。
据我了解, B.m1只是覆盖 A.m1public java.lang.Object m1(java.lang.Object)属于 A并且不应该
上课 B .

最佳答案

这是一种合成桥法。

在 Java 字节码中,方法只覆盖具有完全相同签名的方法。如果 B 没有任何 Object m1(Object) 的实例,那么任何调用它的尝试都会调用 A 中的实现,这不是您想要的。因此,编译器插入了一个合成桥方法,它简单地调用 B m1(Object) .这种行为不是 Scala 特有的——它也发生在纯 Java 中。

您可以通过检查反汇编更详细地查看它。如果我编译和反汇编以下代码

class A
{
def m1(other: AnyRef): AnyRef = {
println("This is A.m1(AnyRef)")
other
}
}

class B extends A {
override def m1(other: AnyRef): B = {
println("This is B.m1(AnyRef)")
this
}
}

B的相关部分是
.method public m1 : (Ljava/lang/Object;)LB; 
.code stack 2 locals 2
L0: getstatic Field scala/Predef$ MODULE$ Lscala/Predef$;
L3: ldc 'This is B.m1(AnyRef)'
L5: invokevirtual Method scala/Predef$ println (Ljava/lang/Object;)V
L8: aload_0
L9: areturn
L10:
.end code
.methodparameters
other final
.end methodparameters
.end method

.method public bridge synthetic m1 : (Ljava/lang/Object;)Ljava/lang/Object;
.code stack 2 locals 2
L0: aload_0
L1: aload_1
L2: invokevirtual Method B m1 (Ljava/lang/Object;)LB;
L5: areturn
L6:
.end code
.methodparameters
other final
.end methodparameters
.end method

如您所见,方法 m1 (Ljava/lang/Object;)Ljava/lang/Object;只需将参数转发到 m1 (Ljava/lang/Object;)LB; .

关于scala - 反编译 Scala 代码 : why there are two overridden methods in the derived class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48968411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com