Java反射:查看方法中的代码行?
我希望能够使用java反射(或任何其他可能存在的方法)提取方法的内部 我有一个测试数据,我在其中生成不同样式的图表。我希望能够显示图表,然后在旁边的面板中显示创建该图表的java代码 我所需要做的就是进入这些方法,并从中吸取教训。反射允许这样吗Java反射:查看方法中的代码行?,java,reflection,Java,Reflection,我希望能够使用java反射(或任何其他可能存在的方法)提取方法的内部 我有一个测试数据,我在其中生成不同样式的图表。我希望能够显示图表,然后在旁边的面板中显示创建该图表的java代码 我所需要做的就是进入这些方法,并从中吸取教训。反射允许这样吗 chart = TestData.createChart1(); chart.display() chart = TestData.createChart2(); chart.display() chart = TestData.createChart3
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组件,该组件构建一个完整的符号表,包括每个定义对提供定义的源代码点的引用(特别是对树的引用)。然后可以使用该符号表查找限定名称,获取定义树并打印它
然后在“analyze”方法中,执行任何您想要显示对象的操作,比如Json序列化、Xml。。。或者如果结果是可利用的,则只需一个toString。不,您不能使用反射来实现这一点。你需要做字节码分析。你真正想实现什么?我一直在胡闹我的测试代码,我想要一个自动的过程,用我正在创建的可视化图表连接测试数据。我认为解析Java文件是唯一简单的方法,只需重构,将这些局部变量作为字段放入DTO对象中即可。创建一个返回这样一个对象的方法,并在任何需要的地方使用它。无需反射或字节码分析。
chart = TestData.createChart1();
analyze(chart);
chart.display();