【发布时间】:2015-08-26 06:59:50
【问题描述】:
我试图找出 .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 Virtual Machine Specification 的问题,但我不得不承认我没能通过这份文档找到自己的方法。
这样设计有什么原因吗?
编辑:
由于我收到了所有好的答案,我在接口和实现类中添加了一些行,以支持答案中的陈述:s
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) 的名称不同? -
@JonnyHenly 我试图表达这一点,是的 ;-)
-
这更像是一个猜测,但可能是由于
abstract关键字?从 C++ 的角度来看,可以说:定义方法原型时,参数的名称无关紧要。也是discouraged to use abstract on interface(-method)s -
@Turing85 好点。因此,我添加了两种方法,一种带有“抽象”,一种没有。两者(我在屏幕截图上没有这个)都错过了变量名。
-
@Turing85
javap -l -c确实显示了默认方法的LocalVariableTable,JD-Gui 似乎也显示了它。
标签: java bytecode javap jd-gui