加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 18:38:00 所属栏目:安全 来源:网络整理
导读:我正在玩反思,以实现对特质的深入分析.我想得到的一件事是设置成员字段的初始值.例如,在特征中: trait A { val x: Int = 3 val y: String = "y"} 知道3和“y”会很高兴.我没有在API中找到与此任务相关的任何内容,并且由于以下输出(由scalac -Xprint生成):
我正在玩反思,以实现对特质的深入分析.我想得到的一件事是设置成员字段的初始值.例如,在特征中:

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 $类.$init $调用no-op并使值无法恢复.

证明:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读