情况似乎异常,但我被要求构建序列化程序,它将通过连接“get”方法的结果将对象解析为字符串。这些值的显示顺序与它们在源代码文件中声明的“get”等效顺序相同。
所以,例如,我们有
Class testBean1{
public String getValue1(){
return "value1";
}
public String getValue2(){
return "value2";
}
}
结果应为:
"value1 - value2"
不是
"value2 - value1"
根据文档,无法使用Class
对象完成。但我想知道我是否可以在“* .class”文件中找到这些信息还是丢失了?如果存在这样的数据,也许有人知道为此目的准备使用的工具?如果无法找到此类信息,请提出最实用的方法来实现目标。我想过要为应该序列化的类的getter添加一些自定义注释。
答案 0 :(得分:3)
如果您需要,则必须解析源代码,而不是字节代码。
有许多库将源文件解析为节点树,我最喜欢的是javaparser(托管在code.google.com上),在稍微修改过的版本中,它也被春天roo。
在the usage page上,你可以找到一些样本。基本上,您将需要使用侦听MethodDefinitions的访问者。
答案 1 :(得分:1)
我认为这些信息不会被保留。
例如, JAXB具有@XmlType(propOrder="field1, field2")
,您可以在其中定义字段在序列化为xml时的顺序。你可以实现类似的东西
答案 2 :(得分:1)
虽然反射不再存在(我认为java 7),它们按照它们在源代码中出现的顺序给出了方法,但是类文件似乎仍然(从Java 8开始)包含顺序中的方法它们出现在源代码中。
因此,您可以解析类文件以查找方法名称,然后根据找到每个方法的文件偏移量对方法进行排序。
如果你想以一种不那么hacky的方式做到这一点,你可以使用Javassist,它将为你提供每个声明方法的行号,这样你就可以按行号对方法进行排序。
答案 3 :(得分:0)
将自定义注释写入商店订购数据,然后使用Method.getAnnotation(Class annotationClass)
答案 4 :(得分:0)
编辑:这仅适用于具体类(要检查的类具有自己的.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 extends List<Method>> 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<Method>() {
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