作者:AmenTo_AT | 来源:互联网 | 2022-12-22 13:29
从Java 8开始,允许在接口中预定义方法.其中一些标准实现已经在诸如CharSequence之类的"标准"接口上实现.如果您尝试使用JVM 7读取Java 8 ByteCode(例如Java主文件夹的rt.jar),则会发生错误.
例如,java.lang.CharSequence类型无法解析.
这可能不是级别之间的唯一区别,但我想了解新字节代码的结构.
public interface com.company.ITest {
public void HelloWorld();
Code:
0: getstatic #1 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #2 // String hello world
5: invokevirtual #3 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
这个Bbytecode是由这个Javacode制作的:
public interface ITest {
default void HelloWorld(){
System.out.println("hello world");
}
}
所以这是我的问题:默认界面如何影响常量池?
这些标志是否相关:
CONSTANT_MethodHandle CONSTANT_MethodType CONSTANT_InvokeDynamic
Anurag Sharm..
5
举几个例子:
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public class Clazz implements A {
}
从客户端代码的角度来看,默认方法只是普通的虚方法.因此名称 - 虚拟扩展方法.因此,如果客户端代码调用默认方法的示例将在调用站点生成invokeinterface.
A clazz = new Clazz();
clazz.foo(); // invokeinterface foo()
Clazz clazz = new Clazz();
clazz.foo(); // invokevirtual foo()
在默认方法冲突解决的情况下,当我们覆盖默认方法并且希望将调用委托给其中一个接口时,推断出invokespecial,因为我们将专门调用该实现:
public class Clazz implements A, B {
public void foo(){
A.super.foo(); // invokespecial foo()
}
}
public void foo();
Code:
0: aload_0
1: invokespecial #2 // InterfaceMethod A.foo:()V
4: return
如您所见,invokespecial指令用于调用接口方法foo().从字节码的角度来看,这也是新的东西,因为之前你只能通过super调用指向类(父类)的方法,而不是接口.
1> Anurag Sharm..:
举几个例子:
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public class Clazz implements A {
}
从客户端代码的角度来看,默认方法只是普通的虚方法.因此名称 - 虚拟扩展方法.因此,如果客户端代码调用默认方法的示例将在调用站点生成invokeinterface.
A clazz = new Clazz();
clazz.foo(); // invokeinterface foo()
Clazz clazz = new Clazz();
clazz.foo(); // invokevirtual foo()
在默认方法冲突解决的情况下,当我们覆盖默认方法并且希望将调用委托给其中一个接口时,推断出invokespecial,因为我们将专门调用该实现:
public class Clazz implements A, B {
public void foo(){
A.super.foo(); // invokespecial foo()
}
}
public void foo();
Code:
0: aload_0
1: invokespecial #2 // InterfaceMethod A.foo:()V
4: return
如您所见,invokespecial指令用于调用接口方法foo().从字节码的角度来看,这也是新的东西,因为之前你只能通过super调用指向类(父类)的方法,而不是接口.