Я пытаюсь найти причину странного эффекта с файлами .class. Вроде для интерфейсов имена переменных, передаваемых в функцию, не указаны, а в классах реализации они есть. Я наткнулся на этот эффект при декомпиляции некоторых моих собственных файлов классов с помощью JD-Gui.
Я проверил это с этими двумя файлами:
Person.java
public interface Person {
public abstract void setName( String name );
public void setAge( int age );
}
PersonImpl.java
public class PersonImpl implements Person {
@Override
public void setName(String name) {
System.out.println("This is my name: " + name);
}
@Override
public void setAge(int age) {
System.out.println("This is my age: " + age);
}
}
JD-Gui возвращает это при декомпиляции:
Используя javap -verbose x.class
, я получаю аналогичные результаты: сигнатуры печатных методов различаются от интерфейса к классу реализации. В одном отсутствуют имена переменных, как я указал их в своем источнике, в другом они есть.
Я попытался ответить на свой вопрос, изучая спецификацию виртуальной машины Java. но должен признать, что я не смог найти свой путь через этот документ.
Есть ли причина, почему это было разработано таким образом?
Изменить:
Из-за всех хороших ответов, которые я получил, я добавил несколько строк в свой интерфейс и класс реализации, чтобы подтвердить утверждения из ответа:
Person.java
default public void yawn(int count) {
for (int i = 1; i <= count; i++)
System.out.println("uaaaaah ....");
}
JD-Gui умеет определять имя параметра:
JavaP может перечислить его в LocalVariableTable:
Когда я добавляю абстрактный метод в реализующий класс и делаю весь класс абстрактным (что мне нужно, потому что он содержит один абстрактный метод)...
PersonImpl.java
public abstract void setPlanet( String planet );
... то JD-Gui не может декомпилировать этот файл класса. Но, к счастью, javap все еще может сбросить файл. Все методы, которые не являются абстрактными, сохраняют свои LocalVariableTable. А у абстрактного метода есть сигнатура, но нет ни Code, ни Lines, ни даже LocalVariableTable (это и ожидалось)
String paramString
) отличается по имени от параметра(ов) реализации (String name
)? - person Jonny Henly   schedule 10.06.2015abstract
? Глядя на это с точки зрения C++, можно сказать: при определении прототипа метода имя параметра не имеет значения. Также не рекомендуется использовать абстрагироваться от интерфейсов (-методов) - person Turing85   schedule 10.06.2015default
и вы выполняетеjavap -verbose ...
, вы увидите имя переменной. Не могли бы вы проверить с помощью JD-Gui, видит ли он имя методаdefault
? - person Turing85   schedule 10.06.2015javap -l -c
действительно показываетLocalVariableTable
для методов по умолчанию, и JD-Gui, похоже, тоже это показывает. - person Vivin Paliath   schedule 10.06.2015abstract
лишний и не рекомендуется. Определения методов неявно абстрактны в интерфейсах (если вы не предоставляете метод по умолчанию). - person Vivin Paliath   schedule 10.06.2015