Ситуация, кажется, является аварийной, но меня попросили создать сериализатор, который проанализирует объект в строку путем конкатенации результатов, "получают" методы. Значения должны появиться в том же порядке, как их "становиться" эквивалентным объявляется в файле исходного кода.
Так, например, мы имеем
Class testBean1{
public String getValue1(){
return "value1";
}
public String getValue2(){
return "value2";
}
}
Результат должен быть:
"value1 - value2"
Нет
"value2 - value1"
Это не может быть, покончили Class
объект согласно документации. Но интересно, могу ли я найти эту информацию в "*.class" файле, или это потеряно? Если такие данные существуют, возможно, кто-то знает, что готовое использует инструмент с этой целью? Если такая информация не может быть найдена, предложите самый профессиональный способ достигнуть цели. Я думал о добавлении некоторых пользовательских аннотаций к методам считывания класса, который должен быть сериализирован.
Если вам это нужно, то вы должны разбирать исходный код, а не байт-код.
Есть несколько библиотек, которые разбирают исходный файл в дерево узлов, моя любимая - javaparser (размещена на code.google.com), которая в слегка измененной версии также используется в spring roo.
На странице использования вы можете найти несколько примеров. В основном вы захотите использовать Visitor, который слушает MethodDefinitions.
Напишите свою собственную аннотацию для хранения данных заказа, затем используйте Method.getAnnotation (класс annotationClass)
Я не думаю, что информация сохраняется.
JAXB, например, имеет @XmlType (propOrder = "field1, field2")
, где вы определяете порядок полей при их сериализации в xml. Вы можете реализовать нечто подобное
Изменить: это работает только с конкретными классами (класс для проверки имеет свой собственный файл .class) . Я изменил приведенный ниже код, чтобы отразить это. Пока не углубимся в библиотеку ClassFileAnalyzer, чтобы работать с классами напрямую, а не читать их из временного файла, это ограничение существует.
У меня работает следующий подход:
Загрузите и импортируйте следующие библиотеки 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