gpt4 book ai didi

scala - 反射可以提取特征中使用的初始值吗?

转载 作者:行者123 更新时间:2023-12-02 21:11:37 26 4
gpt4 key购买 nike

我正在利用反射(reflection)来实现对特质的深入分析。我想要得到的事情之一是为成员字段设置的初始值。例如,在特征中:

trait A {
val x: Int = 3
val y: String = "y"
}

如果能知道 3 和“y”就好了。我在 API 中没有找到与此任务相关的任何内容,并且由于以下输出(由 scalac -Xprint 生成):

abstract trait A extends Object {
<accessor> def com$hablapps$A$_setter_$x_=(x$1: Int): Unit;
<accessor> def com$hablapps$A$_setter_$y_=(x$1: String): Unit;
<stable> <accessor> def x(): Int;
<stable> <accessor> def y(): String
};
abstract trait A$class extends {
def /*A$class*/$init$($this: com.hablapps.A): Unit = {
$this.com$hablapps$A$_setter_$x_=(3);
$this.com$hablapps$A$_setter_$y_=("y");
()
}
}

恐怕访问它们会非常困难,因为它们保存在 $init$ 方法的主体中。有没有任何(简单)方法可以通过反射获取这些值?

最佳答案

你必须反汇编字节码:

trait A { val x: Int = 3 }

public abstract class A$class extends java.lang.Object{
public static void $init$(A);
Code:
0: aload_0
1: iconst_3
2: invokeinterface #12, 2; //InterfaceMethod A.A$_setter_$x_$eq:(I)V
7: return

参见第 1 行——该值存在的唯一位置是 init 方法的字节码中!

你无法以任何其他方式实现这一点,因为如果你有

trait A { val x: Int = 3 }
trait B extends A { override val x = 7 }
class C extends B {}

你发现C扩展了A$_setter_$x_$eq什么都不做——使得A$class.$init$ code> 调用无操作并使值不可检索。

证明:

public class C extends java.lang.Object implements B,scala.ScalaObject{
public void A$_setter_$x_$eq(int);
Code:
0: return

public void B$_setter_$x_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #11; //Field x:I
5: return

关于scala - 反射可以提取特征中使用的初始值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11563954/

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