java 静态解析与分派

class ParentMain {

    public  static int a=1;

    public static void  sayHello(String s)
    {
        System.out.println("hello"+s);
    }

    public int b=3;

    public void sayWorld(String s)

    {
        System.out.println("world"+s);

    }

}

public class Main extends ParentMain {

    public  static int a=2;

    public static void  sayHello(String s)
    {
        System.out.println("hello"+s+"Main");
    }

    public int b=4;

    public void sayWorld(String s)

    {
        System.out.println("world"+s+"Main");

    }

    public  static void myName()
    {

        System.out.println("myName");
    }


    public static void main(String[] args) {

        ParentMain parentMain =new Main();

        parentMain.sayHello("ttt");

        System.out.println(parentMain.a);

        System.out.println("%%%%%%%%%%%%%%%%%%%%%%%");

        parentMain.sayWorld("sss");

        System.out.println(parentMain.b);

        myName();





    }


}

//java 8 output:
//hellottt
//1
//%%%%%%%%%%%%%%%%%%%%%%%
//worldsssMain
//3
//myName

//结果解析:
//对于结果1,不是2,静态的方法并不支持多态(至于为什么设计不弄成静态的覆写了?有人说提供一种和c语言差不多的形式?)
//在编译的时候,编译器直接根据ParentMain类型来选择ParentMain sayHello操作,
//编译的结果是 
public static void main(java.lang.String[]);
    Code:
       0: new           #13                 // class com/company/Main
       3: dup
       4: invokespecial #14                 // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: pop
      10: ldc           #15                 // String ttt
      12: invokestatic  #16                 // Method com/company/ParentMain.sayHello:(Ljava/lang/String;)V
      15: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: aload_1
      19: pop
      20: getstatic     #17                 // Field com/company/ParentMain.a:I
      23: invokevirtual #18                 // Method java/io/PrintStream.println:(I)V
      26: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      29: ldc           #19                 // String %%%%%%%%%%%%%%%%%%%%%%%
      31: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      34: aload_1
      35: ldc           #20                 // String sss
      37: invokevirtual #21                 // Method com/company/ParentMain.sayWorld:(Ljava/lang/String;)V
      40: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      43: aload_1
      44: getfield      #22                 // Field com/company/ParentMain.b:I
      47: invokevirtual #18                 // Method java/io/PrintStream.println:(I)V
      50: invokestatic  #23                 // Method myName:()V
      53: return

  static {};
    Code:
       0: iconst_2
       1: putstatic     #24                 // Field a:I
       4: return
}


//12行调用的是:
 12: invokestatic  #15                 // Method com/company/ParentMain.sayHello:(Ljava/lang/String;)V
直接是invokestatic ParentMain.sayHello方法(直接调用对象的静态类型的方法)
而invokevirtual指令就会动态绑定:
1.首先找到接受者的实际类型
2.然后在调用相关方法


//总结:
1.编译:
存在静态解析和动态连接:
1.静态解析是在类加载的过程中就把符号引用转化为直接引用(前提是已经可以确定调用版本:静态方法,私有方法,final方法)。

动态连接分为:静态分派和动态分派

2.静态分派(看接受方法的对象静态类型的方法(也只能看静态类型),根据方法签名选择调用哪个方法(参数是看静态类型,不是实体类型(也只能看静态类型))
找不到相关类型的参数,自动转型看能不能找到.
向父类和实现接口转型,看有没有对应静态方法。

如:char类型
可以:
char->int->long->float->double->Character->{Serilaizible,Comparable<Character>}->Object

3.动态分派
invokevirtual指令就会动态绑定:
1.首先找到接受者的实际类型
2.然后在调用相关的哪一个方法

java是静态多分派(参数和方法名),动态单分派(对象类型)





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值