获取声明的方法,使它们出现在源代码中

情况似乎是exception的,但我被要求构建序列化器,它将通过连接“get”方法的结果将对象解析为字符串。 值应与源代码文件中声明的“get”等效值的顺序相同。

所以,例如,我们有

Class testBean1{ public String getValue1(){ return "value1"; } public String getValue2(){ return "value2"; } } 

结果应该是:

 "value1 - value2" 

不是

 "value2 - value1" 

根据文档,无法使用Class对象完成。 但我想知道我是否可以在“* .class”文件中找到这些信息还是丢失了? 如果存在这样的数据,也许有人知道为此目的准备使用的工具? 如果无法找到此类信息,请提出最专业的方法来实现目标。 我想过为应该序列化的类的getter添加一些自定义注释。

如果您需要,则必须解析源代码,而不是字节代码。

有许多库将源文件解析为节点树,我最喜欢的是javaparser (托管在code.google.com上),在稍微修改过的版本中,它也被spring roo使用。

在使用情况页面上,您可以找到一些样本。 基本上,您将需要使用侦听MethodDefinitions的Visitor。

我认为这些信息不会被保留。

例如,JAXB具有@XmlType(propOrder="field1, field2") ,您可以在其中定义字段序列化为xml时的顺序。 你可以实现类似的东西

虽然reflection不再存在(从java 7开始我认为)按照它们在源代码中出现的顺序给出了方法,但是类文件似乎仍然(从Java 8开始)按照它们的顺序包含方法出现在源代码中。

因此,您可以解析类文件以查找方法名称,然后根据找到每个方法的文件偏移量对方法进行排序。

如果你想以一种不那么hacky的方式做,你可以使用Javassist,它将为你提供每个声明方法的行号,因此你可以按行号对方法进行排序。

编写自定义注释以存储排序数据,然后使用Method.getAnnotation(Class annotationClass)

编辑:这仅适用于具体类(要检查的类具有自己的.class文件)。 我更改了下面的代码以反映这一点。 在深入了解ClassFileAnalyzer库以直接使用类而不是从临时文件中读取它们之前,存在这种限制。

以下方法适用于我:

下载并导入libarary ClassFileAnalyzer

添加以下两个静态方法(注意!getClussDump()需要稍微修改才能将类文件写入临时文件:我在这里删除了我的代码,因为它在这一点上非常特殊):

 public static String getClassDump(Class c) throws Exception { String classFileName = c.getSimpleName() + ".class"; URL resource = c.getResource(classFileName); if (resource == null) { throw new RuntimeException("Works only for concreate classes!"); } String absolutePath = ...; // write to temp file and get absolute path ClassFile classFile = new ClassFile(absolutePath); classFile.parse(); Info infos = new Info(classFile, absolutePath); StringBuffer infoBuffer = infos.getInfos(); return infoBuffer.toString(); } public static > S sortMethodsBySourceOrder(Class c, S methods) throws Exception { String classDump = getClassDump(c); int index = classDump.indexOf("constant_pool_count:"); final String dump = classDump.substring(index); Collections.sort(methods, new Comparator() { public int compare(Method o1, Method o2) { Integer i1 = Integer.valueOf(dump.indexOf(" " + o1.getName() + lineSeparator)); Integer i2 = Integer.valueOf(dump.indexOf(" " + o2.getName() + lineSeparator)); return i1.compareTo(i2); }}); return methods; } 

现在,您可以使用任何方法列表调用sortMethodsBySourceOrder(因为排序数组不是很舒服),您将获得排序列表。

它的工作原理是查看类转储常量池,而后者又可以由库确定。

格雷茨,GHad