Чтение строки кода из файла класса

#java #reflection

#java #отражение

Вопрос:

Учитывая StackTraceElement.getLineNumber() , есть ли способ прочитать содержимое этой строки из скомпилированного файла класса? И даже если возможно сопоставить строку, будет ли содержимое файла класса «запутано» компилятором?

Например, если бы у меня было:

 public void myMethod () {
    MyObj m = new MyObj ();   // can I reconstruct this line as String?
}
  

Комментарии:

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

2. И даже если вы декомпилируете его на лету, номера строк все равно не будут совпадать.

3. @KirkWoll: Ну, это было бы вроде как наоборот. Предполагая, что класс был скомпилирован с номерами строк в байт-коде (для отладки), тогда при декомпиляции вы можете сначала выполнить поиск в байт-коде по номеру строки, а затем начать декомпиляцию с этого момента.

Ответ №1:

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

Ответ №2:

вы можете включить исходный файл в свой файл war / jar, который вы можете прочитать как файл. Байт-код содержит только номер строки, а не фактический код

Ответ №3:

Вы могли бы извлечь инструкции по байт-кодированию из файла класса (Foo.class ), но не строку, которая представляет исходный код. Однако, учитывая исходный файл и номер строки, вы могли бы вместо этого прочитать строку из исходного файла (Foo.java ), используя стандартные методы чтения файлов.

Чтобы получить представление о том, какая информация содержится в файле .class, ознакомьтесь с javap инструментом. Я полагаю, технически вы могли бы сделать наилучшее предположение об источнике, который скомпилирован для этого класса, или запустить на нем декомпилятор, но номера строк не будут точно совпадать, форматирование будет совершенно другим, и, возможно, что крайне важно, не будет комментариев или аннотаций с использованием уровня хранения исходного кода.