Получить объявленные методы в порядке их появления в исходном коде - PullRequest
9 голосов
/ 30 июня 2010

Ситуация кажется ненормальной, но меня попросили создать сериализатор, который будет анализировать объект в строку путем объединения результатов методов "get". Значения должны отображаться в том же порядке, в каком их «get» эквивалент объявлен в файле исходного кода.

Так, например, у нас есть

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

  public String getValue2(){
   return "value2";
  }
 }

Результат должен быть:

"value1 - value2"

Не

"value2 - value1"

Это не может быть сделано с Class объектом согласно документации. Но мне интересно, могу ли я найти эту информацию в файле "* .class" или она утеряна? Если такие данные существуют, может, кто-то знает готовый инструмент для этой цели? Если такая информация не может быть найдена, пожалуйста, предложите наиболее профессиональный способ достижения цели. Я думал о добавлении каких-то пользовательских аннотаций к получателям класса, которые должны быть сериализованы.

Ответы [ 5 ]

3 голосов
/ 30 июня 2010

Если вы хотите проанализировать исходный код, а не байт-код.

Существует несколько библиотек, которые анализируют исходный файл в дереве узлов, мой любимый - javaparser (размещено на code.google.com), который в слегка измененной версии также используется Spring Roo.

На странице использования вы можете найти некоторые образцы.В основном вы захотите использовать Visitor, который прослушивает MethodDefinitions.

1 голос
/ 26 июля 2014

Хотя рефлексия больше не (по-моему, в Java 7) дает вам методы в том порядке, в котором они появляются в исходном коде, файл класса, по-видимому (все еще в Java 8) содержит методы в порядке в котором они появляются в исходном коде.

Итак, вы можете проанализировать файл класса в поисках имен методов, а затем отсортировать методы по смещению файла, в котором был найден каждый метод.

Если вы хотите сделать это менее хакерским способом, вы можете использовать Javassist, который даст вам номер строки каждого объявленного метода, так что вы можете сортировать методы по номеру строки.

1 голос
/ 30 июня 2010

Я не думаю, что информация сохраняется.

Например, JAXB имеет @XmlType(propOrder="field1, field2"), где вы определяете порядок полей, когда они сериализуются в XML.Вы можете реализовать нечто подобное

0 голосов
/ 02 июля 2010

Редактировать: Это работает только для конкретных классов (класс для проверки имеет свой собственный файл .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 с любым списком методов (поскольку сортировка массивов не очень удобна), и вы получите список обратно отсортированным.

Он работает, просматривая постоянный пул дампов классов, который, в свою очередь, может быть определен библиотекой.

Greetz, GHAD

0 голосов
/ 30 июня 2010

Напишите свою собственную аннотацию для хранения данных заказа, затем используйте Method.getAnnotation (Class annotationClass)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...