Получение исходного кода Java из имени класса - PullRequest
3 голосов
/ 07 июля 2010

Есть ли способ получить исходный код Java из имени класса?

Например, если у меня есть доступ к библиотеке с классом java.io.File, мне нужен ее исходный код.

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

Скажем, у вышеупомянутого класса есть этот метод:

int method (User user) {...}

Мне нужно было бы получить исходный код User и т. Д. И т. Д. С его внутренними классами.

Ответы [ 7 ]

7 голосов
/ 07 июля 2010

Есть ли способ получить исходный код Java из имени класса?Например: ...

Вам может потребоваться одно из нескольких возможных решений.Не зная, что вы действительно хотите сделать с информацией, мы не можем быть очень точными с нашими рекомендациями, но я бы начал с того, что по возможности отгоню вас от исходного кода. Исходный код JSE доступен онлайн, как и многие библиотеки с открытым исходным кодом, но это не всегда так.Кроме того, вам нужно поддерживать все это организованным, когда вы захотите его найти, очень похоже на путь к классам, тогда как объекты Class гораздо проще получить и манипулировать ими без необходимости повторного анализа текста.

Reflection

Если вам просто нужна информация о классе во время выполнения, просто используйте Java Reflection API .С его помощью, имея Объект класса , вы можете, например, получить типы определенного поля, перечислить все поля и перебрать их и т. Д.:

Class clazz = User.class;
Field field = clazz.getDeclaredField("var");
System.out.println(field.getType().getName());

Отражениеполезен для поиска информации о классах в программе, и, конечно, вы можете пройтись по всему дереву без необходимости искать исходный код или что-то анализировать.

Помните, что вы можете искать объект класса (если онна пути к классам во время выполнения) с Class.forName("MyClass") и отражением результирующего класса.

Манипуляция байт-кодом

Если вам нужно больше информации, и вы действительно хотите манипулировать классами, вам нужна манипуляция байт-кодом,Некоторые пытались сгенерировать исходный код, скомпилировать в байт-код и загрузить в свою программу, но поверьте мне - использование надежного API для манипулирования байт-кодом намного, намного проще.Я рекомендую ASM .

С его помощью вы можете не только получать информацию о классе, но и добавлять новые поля, новые методы, создавать новые классы ... даже загружать несколько вариантов классаесли вы чувствуете себя оскорбительным.Примером использования ASM может быть , найденный здесь .

Декомпиляция

Если вам действительно нужен исходный код, а его нет, вы можете декомпилироватьэто из объекта класса, использующего один из различных декомпиляторов.Они используют ту же информацию и методы, что и вышеупомянутые два, но идут дальше и [пытаются] генерировать исходный код.Обратите внимание, что это не всегда работает.Я рекомендую Jode, но приличный список и сравнение с другими доступны онлайн .

File Lookup

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

Class clazz = User.class;
String path = clazz.getPackage().getName().replaceAll("\\.","/");
File sourceFile = new File(path, clazz.getName() + ".java")

Вам нужно больше логики для проверки типа класса, поскольку, очевидно, Примативы не имеют определений классов, и вы хотите обрабатывать типы массивов по-разному.

Вы можете искать класс по имени (если файлы .class находятся в вашем пути к классам) с помощью Class.forName("MyClass").

3 голосов
/ 07 июля 2010

Лучшая и самая простая ставка может быть javap

hello.java

public class hello
{
    public static void main(String[] args)
    {
    System.out.println("hello world!");
    world();
    }

    static public void world()
    {
    System.out.println("I am second method");
    }
}

сделайте javap hello и вы получите это:

Compiled from "hello.java"
public class hello extends java.lang.Object{
    public hello();
    public static void main(java.lang.String[]);
    public static void world();
}
3 голосов
/ 07 июля 2010

Вы можете получить хорошее приближение источника из класса файла , используя JAVA-декомпилятор по вашему выбору . Однако, если вы действительно ищете источник java.io.File, вы можете скачать этот .

2 голосов
/ 07 июля 2010

Да, если вы загружаете исходный код. Он доступен для публичного скачивания на официальной странице загрузки.

Если вы используете Eclipse всякий раз, когда используете класс, вы можете щелкнуть правой кнопкой мыши> View Source (или просто щелкнуть по классу> F3), и он откроет новую вкладку с источником.

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

Есть ли способ получить исходный код Java из имени класса?

Ответ сложен, не в последнюю очередь из-за неопределенности вашего вопроса. (Несмотря на пример).

  • Как правило, невозможно получить реальный, реальный исходный код Java для класса.

  • Если у вас есть (например) файл ZIP или JAR, содержащий исходный код для классов, тогда просто извлечь соответствующий исходный файл на основе полного имени класса. Но вы должны сначала получить эти файлы ZIP / JAR.

  • Если вас интересуют только сигнатуры методов, имена и типы атрибутов и т. Д., Большая часть этой информации доступна во время выполнения с помощью API-интерфейсов отражения Java. Однако это зависит от того, сколько будет доступно классов, скомпилированных с отладочной информацией (см. Параметр -g для компилятора javac). И это нигде не похоже на информацию, которую вы можете получить из реального исходного кода.

  • Декомпилятор может генерировать скомпилированный исходный код для класса из файлов байт-кода. Но декомпилированный код не будет похож на исходный код.

  • Полагаю, если у вас есть URL-адрес веб-сайта, заполненного javadocs для классов, вы можете перейти от имени класса, имени метода или открытого атрибута к соответствующему URL-адресу javadoc во время выполнения. Вы могли бы даже "очистить экран" описания от Javadocs. Но опять же, это не настоящий исходный код.

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

Если ваша цель - получить информацию о том, что находится в классе, вам может показаться, что API отражения Java является более простым подходом.Вы можете использовать отражение для поиска полей, методов, конструкторов, иерархии наследования и т. Д. Класса во время выполнения без необходимости иметь исходный код для этого класса.

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

Итак, вы пытаетесь получить класс Java при выполнении .Для этого вам нужно Java отражений .

...