Сохранение имен параметров / аргументов в скомпилированных java-classах
Когда я компилирую что-то вроде этого:
public class MyClass { void myMethod(String name, String options, String query, String comment) { ... } }
и скомпилировать это в файл classа, кажется, что имена аргументов теряются. То есть, когда какой-то другой код Java ссылается на MyClass
и хочет вызвать или перезаписать myMethod
, моя IDE (в настоящее время Eclipse), похоже, получает эту подпись метода из файла-classа:
void myMethod(String arg0, String arg1, String arg2, String arg3);
Я знаю, что Eclipse (и, возможно, другие IDE тоже) позволяет мне предоставить ссылку на источник или javadoc (как указал Бишибуш) MyClass
и может воспользоваться этим. Но мне любопытно, есть ли способ сказать javac
включить имена в class-файл, чтобы пользователи этого classа могли видеть имена аргументов, даже если они имеют только файл classа.
- Как показать консольный вывод / окно в приложении форм?
- Статические конечные значения Java заменяются в коде при компиляции?
- Как скомпилировать Qt 5 под Windows или Linux, 32 или 64 бит, статические или динамические на VS2010, VS2012, VS2013 или VS2015 Express или g ++
- Как определить путь classа компиляции * только * в Gradle?
- Компилировать код с помощью JavaFX 2.0 (используя командную строку)
Решение для classов
Когда я компилирую class с java -g:vars
, имена параметров includeся в файл classа. -g:vars
похоже, эквивалентен Eclipse -> свойствам проекта -> компилятор Java -> добавлять атрибуты переменной к сгенерированным файлам classов.
Это решение было предложено несколькими авторами, но ответ от Ника заставил меня поверить.
На моей машине Eclipse иногда использовал эту информацию, иногда ее не было, что, вероятно, было моей ошибкой или ошибкой в Eclipse, но не проблема с файлами classов или компиляцией. В любом случае, теперь я знаю, что информация определенно присутствует.
Но никакого решения для интерфейсов
Хотя это работает (вроде) отлично для classов, оно не работает для интерфейсов.
Для меня логическая причина заключается в том, что -g: vars предоставляет только имена локальных переменных, что также указывает документация для javac. В теле метода параметры очень похожи на локальные переменные, поэтому они покрываются -g: vars. интерфейсные методы не имеют тел, поэтому они не могут иметь локальные переменные.
Мой первоначальный вопрос задавал только classы, потому что я не знал, что может быть какая-то разница.
Формат файла classа
Как указывал gid , формат файла classа не поддерживает сохранение имен параметров. Я нашел раздел в спецификации classа classа, который описывает стробу данных, которая должна воспитывать имена параметров методов, но это определенно не используется при компиляции интерфейсов.
При компиляции classа я не могу определить, используется ли упомянутая структура данных, или если Eclipse указывает имена параметров из использования параметров внутри тела метода. Эксперт мог бы прояснить это, но это не так важно, я думаю.
- Какова цель настройки «Предпочитаю 32-бит» в Visual Studio 2012 и как она работает?
- На лету, компиляция Java-кода в памяти для Java 5 и Java 6
- Почему Swift компилируется так медленно?
- «% d» ожидает аргумент типа «int», но аргумент 2 имеет тип «long unsigned int»
- Очень медленное время компиляции на Visual Studio 2005
- Как ускорить время компиляции моего проекта C ++ с поддержкой CMake?
- Почему я получаю ошибку компиляции «org / codehaus / groovy / control / CompilationFailedException»?
- Перекрестная компиляция Перейти на OSX?
Чтобы сохранить имена в файле classа для целей отладки, попробуйте свойства проекта, компилятор Java, затем «Добавить переменные атрибутов в сгенерированные файлы classов» (см. Справку Eclipse ).
Компиляция следующего источника:
public class StackOverflowTest { public void test(String foo, String bar) { // blah } }
Декомпилируется в:
// Compiled from StackOverflowTest.java (version 1.5 : 49.0, super bit) public class StackOverflowTest { // Method descriptor #6 ()V // Stack: 1, Locals: 1 public StackOverflowTest(); 0 aload_0 [this] 1 invokespecial java.lang.Object() [8] 4 return Line numbers: [pc: 0, line: 1] Local variable table: [pc: 0, pc: 5] local: this index: 0 type: StackOverflowTest // Method descriptor #15 (Ljava/lang/String;Ljava/lang/String;)V // Stack: 0, Locals: 3 public void test(java.lang.String foo, java.lang.String bar); 0 return Line numbers: [pc: 0, line: 4] Local variable table: [pc: 0, pc: 1] local: this index: 0 type: StackOverflowTest [pc: 0, pc: 1] local: foo index: 1 type: java.lang.String [pc: 0, pc: 1] local: bar index: 2 type: java.lang.String }
См. Имена параметров сохраняются в файлах classов.
Я бы посоветовал вам изучить, как скомпилирован ваш источник, какую версию он компилирует и т. Д.
РЕДАКТИРОВАТЬ:
Ах, я вижу, что для интерфейсов это другое – они, похоже, не имеют этой информации для отладчика, которая, как мне кажется, имеет смысл. Я не думаю, что это будет так, если вы просто захотите увидеть имена параметров при редактировании источника, вам нужно перейти на маршрут javadoc, как предлагает Nagrom_17 (прикрепить источник).
Вам не нужен источник, чтобы имена arg появились в Eclipse … Если вы укажете Javadoc, Eclipse отобразит args.
Это может помочь скомпилировать с поддержкой отладки, которая хранит все имена в файле .class.
хотя я не знаю, учитывает ли это Eclipse.
В структуре данных файла classов нет поддержки для хранения имен параметров для любого метода, независимо от того, какие параметры javac вы используете.
Чтобы увидеть исходные имена в среде IDE, вы должны предоставить их либо javadoc, либо источник.
Если у вас есть определенная потребность попасть на них во время выполнения, можно добавить annotations к параметрам, но вам придется создавать свои собственные, поскольку не используется стандартный набор.
Извините, не может быть более полезным
EDIT : я полностью исправлен … формат файла classа явно имеет место для именованных параметров ( JLS 4.7 )
Я не вижу, как, черт возьми, вы можете их использовать, используя java.lang.reflect.*
Eclipse найдет имена аргументов, если вы javac -g:vars
в файл classа информацию об отладке: javac -g:vars
должно быть достаточно.
Вам не нужен отдельный Javadoc-файл, который вы можете создать «inline» javadocs в Eclipse, используя специальный комментарий с двумя звездочками (*) после первого коллажа многострочного комментария.
пример кода:
public class MyClass { /** * documentation of your method * * @param name a String describing the name * @param options used to describe current option * @param query * @param comment * @return void */ void myMethod(String name, String options, String query, String comment) { ... } }