Java中的Default方法

Java中的Default方法

Java8在接口中新引入了一种default方法。目的是保留原先的结构,只将改动加入到接口中。

public interface A {

    default void c(){
        System.out.println("A.c");
    }
}
public interface B {

    default void c(){
        System.out.println("B.c");
    }
}

如果一个类同时实现两个接口,这两个接口中有同样的方法时,编译时会报错。
解决方法如下:

public class whoisc implements A, B {

    public void c(){

//      A.super.c();//invokespecial 
        B.super.c();//指明调用B接口中的方法
//      或者复写该方法

    }

    public static void main(String[] args){

        whoisc realc = new whoisc();
        realc.c();//invokevirtual 

        A realcc = new whoisc();
        realcc.c();//invokeinterface
    }
}

Java每个class文件有一个虚方法表,虚方法表包含指向类中方法的字节码。该表继承父类中的特定类,扩展父类中的新方法。

    class superClass{
        public void m1(){};
        public void m2(){};

    }

    class thisClass extends superClass{
        public void m2(){};
        public void m3(){};
    }

virtual Method Table

superClass

  1. superClass/m1()

  2. superClass/m2()

thisClass

  1. superClass/m1()

  2. thisClass/m2()

  3. thisClass/m3()

thisClass的虚方法表继承了superClass,并且覆写了m2的链接。

JVM会记住虚方法表中各方法的调用位置,以便在子类中优化优化invokevirtual的调用。

但是对于invokeinterface,这种调用优化就不起作用了。
如下:


interface thisInterface{
        void interfaceM1();
    }

    class anotherClass extends thisClass implements thisInterface{
        public void m4(){};
        public void interfaceM1(){};
    }

    class anotherInterfaceClass implements thisInterface{
        public void m5(){};
        public void interfaceM1(){};
    } 

虚方法表中的方法调用位置

anotherClass

  1. superClass/m1()

  2. thisClass/m2()

  3. thisClass/m3()

  4. anotherClass/m4()

  5. thisInterface/interfaceM1()

anotherInterfaceClass

  1. anotherInterfaceClass/m5()

  2. thisInterface/interfaceM1()

此时anotherClass中调用的interfaceM1()方法位置,与anotherInterfaceClass中调用的interfaceM1()方法位置,并不存在继承关系,所以位置的次序也不是顺序增加的。在invokevirtual中的调用优化在invokeinterface中也就不适用了。

JVM中的调用指令

  • invokevirtual指令用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),这也是 Java 语言中最常见的方法分派方式。
  • invokeinterface指令用于调用接口方法,它会在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。invokeinterface必须在运行时检查方法的对象引用。

  • invokespecial指令用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。

  • invokestatic 指令用于调用类方法(static方法)。

参考

StackOverFlow What is the point of invokeinterface?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值