我正在计算.txt文件中的方法数,这个文件是用 java ```BufferedReader br = new BufferedReader(new FileReader("fichiertext.txt"));try {Method[] sd = br.getClass().getDeclaredMethods();System.out.println(sd);
java
xqkwcwgp1#
你要的是 BufferedReader 定义本身。这就是为什么你写的东西行不通,你写的东西背后的想法永远行不通。java,运行时,根本不知道java(源代码)是什么。api中没有允许您执行此操作的内容。@sma的两个建议也都不起作用。他们的第一个建议是,将代码通过java编译器运行(任何给定的java虚拟机运行都可能有或没有- JavaCompiler 是java中的一个类,可以用它来编译东西,但它可能返回 null 表示没有可用的编译器)。但是,即使有一个可用的,这也不起作用:要完全编译源文件,需要它的所有依赖项。然而,要计算方法,你不需要知道这些。如果一个方法引用, ImmutableList ,那么你仍然可以算作:是的。1方法。即使你不知道 ImmutableList 可能是指。而完整的编译运行无法完成任务,除非它知道。此外,一旦编译,到目前为止的策略将涉及到在编译的结果中加载,这样您就可以调用 .getDeclaredMethods . 不要这样做-在类中加载将初始化它们。如果类的静态初始值设定项挂起、抛出异常或格式化磁盘,那么要么最终没有类对象可调用 .getDeclaredMethods() 或者更糟的是,你的磁盘被格式化了。因此,您不想编译源文件,也不想初始化生成的类文件,即使您成功地编译了它。sma的第二个建议涉及正则表达式。这是愚蠢的建议-正则表达式不是魔法。它们可以解析正则语法。java语法是不规则的,所以,没有人能做到。那么,你是做什么的?它不容易。您需要的是一个java解析器:一个能够理解java语法的东西。作为第一个常规步骤,解析器将一堆文本转换为所谓的“ast”:一个抽象语法树。它是一个树结构:这样的库返回一个 CompilationUnit 对象,它具有 .getPackage() 对于包声明, List<ImportStatement> getImports() 为了进口,然后 List<TypeDefinitions> getTypeDefs() 对于类型定义,它通常是1(您可以在一个.java文件中放入多个类,只要只有一个是1) public ). 这又会有方法要求所有的内部类、字段、初始值设定项、构造函数和包含的方法,等等。ast是(或不需要是)“链接的”——它可以说,例如类 extends FooBar ,离开 FooBar 作为一个字符串,不让你问foobar的东西包含什么。这很好,因为这意味着即使没有foobar.java,也可以执行此步骤。使用ast,您可以编写循环的代码,并计算您想计算的任何值。要获得ast,您需要一个java解析器。您有3个主要选项:javac-你不能真正使用任何内置的编译器,它不是公共api。它也是gpl许可的,所以除非你也gpl你的代码,你不能合法地这样做。api不是公共的,因为它可以在以后的版本中更改。因此,不建议。ecj—eclipse项目的编译器。它有一个开放源码许可证,速度快,非常准确。然而,这个api并不容易使用,因为它已经在我们这里使用了20年,并且针对速度进行了优化。不错的选择。其他解析器。现在有很多java解析器库,大多数都是经过许可的,其中很多都包含了java语法作为概念证明和示例来说明解析器是如何工作的,并且能够解析非常复杂的东西,比如java。这类语法工具通常缺乏兼容性(它们不支持一些异国情调的java特性,或者它们弄错了某些东西),但它们通常更易于使用。所有这三项都涉及到引入依赖项,对于一个完全没有解析器经验的有经验的程序员来说,它们的工作量相当于一个人一周的工作量。对于一个初级java程序员,hoo boy。棘手的事情。好几个星期。
BufferedReader
JavaCompiler
null
ImmutableList
.getDeclaredMethods
.getDeclaredMethods()
CompilationUnit
.getPackage()
List<ImportStatement> getImports()
List<TypeDefinitions> getTypeDefs()
public
extends FooBar
FooBar
1条答案
按热度按时间xqkwcwgp1#
你要的是
BufferedReader
定义本身。这就是为什么你写的东西行不通,你写的东西背后的想法永远行不通。java,运行时,根本不知道java(源代码)是什么。api中没有允许您执行此操作的内容。
@sma的两个建议也都不起作用。他们的第一个建议是,将代码通过java编译器运行(任何给定的java虚拟机运行都可能有或没有-
JavaCompiler
是java中的一个类,可以用它来编译东西,但它可能返回null
表示没有可用的编译器)。但是,即使有一个可用的,这也不起作用:要完全编译源文件,需要它的所有依赖项。然而,要计算方法,你不需要知道这些。如果一个方法引用,
ImmutableList
,那么你仍然可以算作:是的。1方法。即使你不知道ImmutableList
可能是指。而完整的编译运行无法完成任务,除非它知道。此外,一旦编译,到目前为止的策略将涉及到在编译的结果中加载,这样您就可以调用
.getDeclaredMethods
. 不要这样做-在类中加载将初始化它们。如果类的静态初始值设定项挂起、抛出异常或格式化磁盘,那么要么最终没有类对象可调用.getDeclaredMethods()
或者更糟的是,你的磁盘被格式化了。因此,您不想编译源文件,也不想初始化生成的类文件,即使您成功地编译了它。
sma的第二个建议涉及正则表达式。这是愚蠢的建议-正则表达式不是魔法。它们可以解析正则语法。java语法是不规则的,所以,没有人能做到。
那么,你是做什么的?
它不容易。
您需要的是一个java解析器:一个能够理解java语法的东西。作为第一个常规步骤,解析器将一堆文本转换为所谓的“ast”:一个抽象语法树。它是一个树结构:这样的库返回一个
CompilationUnit
对象,它具有.getPackage()
对于包声明,List<ImportStatement> getImports()
为了进口,然后List<TypeDefinitions> getTypeDefs()
对于类型定义,它通常是1(您可以在一个.java文件中放入多个类,只要只有一个是1)public
). 这又会有方法要求所有的内部类、字段、初始值设定项、构造函数和包含的方法,等等。ast是(或不需要是)“链接的”——它可以说,例如类
extends FooBar
,离开FooBar
作为一个字符串,不让你问foobar的东西包含什么。这很好,因为这意味着即使没有foobar.java,也可以执行此步骤。使用ast,您可以编写循环的代码,并计算您想计算的任何值。
要获得ast,您需要一个java解析器。您有3个主要选项:
javac-你不能真正使用任何内置的编译器,它不是公共api。它也是gpl许可的,所以除非你也gpl你的代码,你不能合法地这样做。api不是公共的,因为它可以在以后的版本中更改。因此,不建议。
ecj—eclipse项目的编译器。它有一个开放源码许可证,速度快,非常准确。然而,这个api并不容易使用,因为它已经在我们这里使用了20年,并且针对速度进行了优化。不错的选择。
其他解析器。现在有很多java解析器库,大多数都是经过许可的,其中很多都包含了java语法作为概念证明和示例来说明解析器是如何工作的,并且能够解析非常复杂的东西,比如java。这类语法工具通常缺乏兼容性(它们不支持一些异国情调的java特性,或者它们弄错了某些东西),但它们通常更易于使用。
所有这三项都涉及到引入依赖项,对于一个完全没有解析器经验的有经验的程序员来说,它们的工作量相当于一个人一周的工作量。
对于一个初级java程序员,hoo boy。棘手的事情。好几个星期。