Сохранение имен параметров / аргументов в скомпилированных классах Java

Когда я собираю что-то вроде этого:

public class MyClass
{
    void myMethod(String name, String options, String query, String comment)
    {
        ...
    }
}

и скомпилировать это в файл класса, кажется, что имена аргументов потеряны. То есть, когда некоторые другие ссылки на код Java MyClass и хочет позвонить или переписать myMethod моя IDE (в настоящее время Eclipse), кажется, получает эту сигнатуру метода из файла класса:

void myMethod(String arg0, String arg1, String arg2, String arg3);

Я знаю, что Eclipse (и, возможно, другие IDE тоже) позволяет мне предоставить ссылку на источник или Javadoc (как указал Bishiboosh) из MyClass и может воспользоваться этим. Но мне любопытно, есть ли способ сказать javac включить имена в файл класса, чтобы пользователи этого класса могли видеть имена аргументов, даже если у них есть только файл класса.

Решение для занятий

Когда я собираю класс с java -g:vars имена параметров включены в файл класса. -g:vars кажется эквивалентным Eclipse -> свойства проекта -> компилятор Java -> добавить атрибуты переменных в сгенерированные файлы классов.

Это решение было предложено несколькими авторами, но ответ Ника, наконец, заставил меня поверить.

На моей машине Eclipse иногда использовал эту информацию, иногда - нет, что, вероятно, было моей ошибкой или ошибкой в ​​Eclipse, но не проблемой с файлами классов или компиляцией. Во всяком случае, теперь я знаю, что информация определенно присутствует.

Но нет решения для интерфейсов

Хотя это работает (вроде) хорошо для классов, это не работает для интерфейсов.

Мне кажется, что логическая причина заключается в том, что -g: vars предоставляет только имена локальных переменных, что также указано в документации для javac. В теле метода его параметры очень похожи на локальные переменные, поэтому они покрываются -g: vars. Методы интерфейса не имеют тел, поэтому они не могут иметь локальные переменные.

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

Формат файла класса

Как указал Гид, формат файла класса не поддерживает хранение имен параметров. Я нашел раздел в спецификации файла класса, который описывает структуру данных, которая должна содержать имена параметров методов, но это определенно не используется при компиляции интерфейсов.

При компиляции класса я не могу сказать, используется ли упомянутая структура данных или Eclipse выводит имена параметров из использования параметров внутри тела метода. Эксперт может уточнить это, но я думаю, что это не так актуально.

6 ответов

Решение

Чтобы сохранить имена в файле классов для целей отладки, попробуйте свойства проекта, Java-компилятор, а затем "Добавить переменные атрибуты в сгенерированные файлы классов" (см. Справку Eclipse).

Составление следующего источника:

public class StackruTest {
    public void test(String foo, String bar) {
        // blah
    }
}

Декомпилируется в:

// Compiled from StackruTest.java (version 1.5 : 49.0, super bit)
public class StackruTest {

    // Method descriptor #6 ()V
    // Stack: 1, Locals: 1
    public StackruTest();
        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: StackruTest

    // 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: StackruTest
            [pc: 0, pc: 1] local: foo index: 1 type: java.lang.String
            [pc: 0, pc: 1] local: bar index: 2 type: java.lang.String
}

Смотрите, имена параметров сохраняются в файлах классов.

Я бы посоветовал вам посмотреть, как компилируется ваш источник, для какой версии он компилируется и т. Д.

РЕДАКТИРОВАТЬ:

Ах, я вижу, что это отличается для интерфейсов - у них, похоже, нет этой информации для отладчика, что, я думаю, имеет смысл. Я не думаю, что будет способ обойти это, если вы просто хотите видеть имена параметров при редактировании источника, вам нужно пойти по пути javadoc, как предлагает Nagrom_17 (присоедините источник).

Вам специально не нужен источник для отображения имен аргументов в Eclipse... Если вы укажете Javadoc, Eclipse отобразит аргументы.

Это может помочь скомпилировать с поддержкой отладки, которая хранит все имена в файле.class.

хотя я не знаю, принимает ли это во внимание Eclipse.

Eclipse подберет имена аргументов, если вы включите отладочную информацию в файл класса: javac -g:vars должно быть достаточно.

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

Чтобы увидеть исходные имена в IDE, вы должны предоставить им либо Javadoc, либо источник.

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

Извините, не могу быть более полезным

РЕДАКТИРОВАТЬ: Я полностью исправлен... формат файла класса явно есть место для именованных параметров ( JLS 4.7)

То, что я не могу видеть, это то, как, черт возьми, вы можете получить их, используя java.lang.reflect.*

Вам не нужен отдельный файл Javadoc, вы можете создавать "встроенные" 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)
    {
        ...
    }
}
Другие вопросы по тегам