Invoke in compiling

Normal method

1
2
int calc(int i, int j) { return i+j; }
static int calc(int i, int j, int k) { return i+j+k; }

javap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int calc(int, int);
Code:
0: iload_1
1: iload_2
2: iadd
3: ireturn

static int calc(int, int, int);
Code:
0: iload_0
1: iload_1
2: iadd
3: iload_2
4: iadd
5: ireturn

Nomal invoke

1
2
3
4
void call() {
calc(12, 13);
AboutInvoke.calc(12, 13, 14);
}

javap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void call();
Code:
0: aload_0
1: bipush 12
3: bipush 13
// Method calc:(II)I
5: invokevirtual #2
8: pop
9: bipush 12
11: bipush 13
13: bipush 14
// Method calc:(III)I
15: invokestatic #3
18: pop
19: return

Compiler generates symbolic references to
the methods(#2 #3) of an instance(Pointer?).

These symbols are store in run-time constant pool.

They are resolved at run-time to determine the actual method location.

Special invoke

Father

1
2
3
4
5
class Father{
int money = 10;
public int haveFun() { return getMoney(); }
private int getMoney() { return money; }
}

Son

1
2
3
class Son extends Father{
void havePunk() { super.haveFun(); }
}

javap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Father play
public int haveFun();
Code:
0: aload_0
// Method getMoney:()I
1: invokespecial #3
4: ireturn

// Son play
void havePunk();
Code:
0: aload_0
// Method Father.haveFun:()I
1: invokespecial #2
4: pop
5: return

invokespecial instruction always pass this to
the invoked method as its first argument.
As usual, it is received in local variable 0(aload_0).

  1. The method in super class call itself’s instance method.
    If the method is private , use invokespecial.

  2. If the sub class call super class’s instance method, all use invokespecial.