Подтвердить что ты не робот

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

Решение для классов

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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Компиляция следующего источника:

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 (прикрепить источник).

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

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

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

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

ИЗМЕНИТЬ: Я полностью исправляю... формат файла класса явно имеет место для именованных параметров (JLS 4.7)

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

Ответ 5

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

Ответ 6

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