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();
}
}
public static void main(java.lang.String[]);
Code:
0: new #13
3: dup
4: invokespecial #14
7: astore_1
8: aload_1
9: pop
10: ldc #15
12: invokestatic #16
15: getstatic #3
18: aload_1
19: pop
20: getstatic #17
23: invokevirtual #18
26: getstatic #3
29: ldc #19
31: invokevirtual #10
34: aload_1
35: ldc #20
37: invokevirtual #21
40: getstatic #3
43: aload_1
44: getfield #22
47: invokevirtual #18
50: invokestatic #23
53: return
static {};
Code:
0: iconst_2
1: putstatic #24
4: return
}
12: invokestatic #15
直接是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是静态多分派(参数和方法名),动态单分派(对象类型)