Сохранение имен параметров / аргументов в скомпилированных классах Java - PullRequest
14 голосов
/ 02 июня 2009

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

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 (как указал Бишибуш) из MyClass и может воспользоваться этим. Но мне любопытно, есть ли какой-нибудь способ сказать javac включить имена в файл класса, чтобы пользователи этого класса могли видеть имена аргументов, даже если у них есть только файл класса.

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

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

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

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

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

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

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

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

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

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

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

Ответы [ 6 ]

8 голосов
/ 02 июня 2009

Чтобы сохранить имена в файле класса для целей отладки, попробуйте свойства проекта, Java-компилятор, затем «Добавить переменные атрибуты к сгенерированным файлам класса» (см. Справка 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
}

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

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

EDIT:

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

7 голосов
/ 02 июня 2009

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

5 голосов
/ 02 июня 2009

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

хотя я не знаю, учитывает ли это Eclipse.

2 голосов
/ 02 июня 2009

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

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

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

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

EDIT : Я полностью исправлен ... формат файла класса явно имеет место для именованных параметров ( JLS 4.7 )

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

1 голос
/ 02 июня 2009

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

0 голосов
/ 02 июня 2009

Вам не нужен отдельный файл 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)
    {
        ...
    }
}
...