Java反射:查看方法中的代码行?

Java反射:查看方法中的代码行?,java,reflection,Java,Reflection,我希望能够使用java反射(或任何其他可能存在的方法)提取方法的内部 我有一个测试数据,我在其中生成不同样式的图表。我希望能够显示图表,然后在旁边的面板中显示创建该图表的java代码 我所需要做的就是进入这些方法,并从中吸取教训。反射允许这样吗 chart = TestData.createChart1(); chart.display() chart = TestData.createChart2(); chart.display() chart = TestData.createChart3

我希望能够使用java反射(或任何其他可能存在的方法)提取方法的内部

我有一个测试数据,我在其中生成不同样式的图表。我希望能够显示图表,然后在旁边的面板中显示创建该图表的java代码

我所需要做的就是进入这些方法,并从中吸取教训。反射允许这样吗

chart = TestData.createChart1();
chart.display()
chart = TestData.createChart2();
chart.display()
chart = TestData.createChart3();
    ...
chart = TestData.createChartN();
chart.display()
在我的一个方法中,我可能有这样的东西:

public static PieChart createChart1() {

    //I WANT ALL THE CODE FROM HERE....

    ArrayList<Segment> values = new ArrayList<Segment>();
    values.add(new Segment(0, null, 15, "music", Color.RED));
    values.add(new Segment(0, null, 52, "photos", Color.BLUE));
    values.add(new Segment(0, null, 33, "applications", Color.GREEN));

    PieChart pieChart = new PieChart(values, "Disk Space Usage");

    pieChart.width = 600;
    pieChart.height = 600;
    pieChart.topOffset = 50;
    pieChart.leftOffset = 50;
    pieChart.rightOffset = 50;
    pieChart.bottomOffset = 50;
    pieChart.initialWidth = 100;
    pieChart.incrementWidth = 50;

    //TO HERE....

    return pieChart;
}
publicstaticpiechart createChart1(){
//我要这里的所有代码。。。。
ArrayList值=新的ArrayList();
添加(新段(0,空,15,“音乐”,颜色.RED));
添加(新段(0,null,52,“照片”,Color.BLUE));
添加(新段(0,null,33,“应用程序”,颜色为.GREEN));
PieChart PieChart=新PieChart(值,“磁盘空间使用”);
pieChart.width=600;
pieChart.height=600;
pieChart.topOffset=50;
pieChart.leftOffset=50;
pieChart.rightOffset=50;
pieChart.bottomOffset=50;
pieChart.initialWidth=100;
pieChart.incrementWidth=50;
//到这里。。。。
返回图表;
}

反射的好处在于它使程序能够访问其源代码的某些方面。不太好的部分是,您可以得到什么是由语言设计者和实现者决定的,因此受到限制。原始源代码是他们不愿意提供的部分。如果他们这样做,每一个编译的反射系统都会包含它的源代码,这将造成巨大的知识产权泄漏

如果您希望通过编程访问计算机程序(包括Java程序)的全部内容,那么称为(PTS)系统的工具类是理想的。这些工具通常用于解析感兴趣的源代码语言,构建内部编译器数据结构(通常是抽象语法树或AST),其中包含源代码的完整等价物(通常包括精确的源代码位置信息)。OP认为真正有用的部分是,PTS通常可以反转解析过程,并从内部结构重新生成源(或指定部分)。作为替代方案,可以使用精确的源位置信息从原始文件中提取原始文本;只有当您关心精确的格式和/或空白中的内容时,这才非常有用

要使用我们的DMS软件再工程工具包获得OP的效果,可以使用DMS的Java前端,并使用以下代码编写一个定制工具:

       (include `Java~v7/ParserComponent.par')
        ...
       (local (;; [myFile string] 
                  [myTree AST:Tree]
              );;
           ...
           (= myFile ... )  ; get a file path from somewhere
           (= myTree (ParserComponent:Parse myFile ...))
           (AST:ScanTree myTree
                 (procedure [subtree AST:Tree]
                     (;;  (ifthen (== (AST:subtree Grammar:Nonterminals:_method_declaration))
                               (;;  (ParserComponent:PrettyPrintFidelity
                                         (AST:GetNthGrammarChild myTree 3) ; the method body
                                         ...
                                     )
                               );;
                          )

                          (return ~t) ; signal to ScanTree to continue looking 
                     );;
                 )
           )AST
       )local
请注意树扫描(将其视为访问者),它查找类型为“method_declaration”的AST节点,该术语字面上取自Java语法。找到这样的AST节点类型后,它导航到方法体并调用DMS的prettyprinter以逼真模式重新生成文本,该模式从原始源代码中复制原始缩进、换行和注释。[所有这些信息都在DMS的目录树中]

如果OP需要一个特别命名的方法;他将使用DMS的NameResolver组件,该组件构建一个完整的符号表,包括每个定义对提供定义的源代码点的引用(特别是对树的引用)。然后可以使用该符号表查找限定名称,获取定义树并打印它

  • java Reflection不允许读取代码行,并且Reflection所依赖的pcode不包含源代码,仅包含已编译的代码(如果使用调试选项编译),还包含行号

  • 由于您的方法“createChart”只创建一个对象,因此您只能分析结果对象(“图表”)的内容


  • 然后在“analyze”方法中,执行任何您想要显示对象的操作,比如Json序列化、Xml。。。或者如果结果是可利用的,则只需一个toString。

    不,您不能使用反射来实现这一点。你需要做字节码分析。你真正想实现什么?我一直在胡闹我的测试代码,我想要一个自动的过程,用我正在创建的可视化图表连接测试数据。我认为解析Java文件是唯一简单的方法,只需重构,将这些局部变量作为字段放入DTO对象中即可。创建一个返回这样一个对象的方法,并在任何需要的地方使用它。无需反射或字节码分析。
    chart = TestData.createChart1();
    analyze(chart);
    chart.display();