1. 调用函数
1.1 调用成员函数
public class Test { int addTwo(int i, int j){ return i+j; }
public static void main(String[] args){ Test t = new Test(); t.addTwo(10,11); addTwoStatic(11,12); }
}
|
1.2 调用父类函数
class SuperTest{ public int getInfo(){ return 1; } }
public class Test extends SuperTest { public int get(){ return super.getInfo(); }
}
|
1.3 调用静态函数
static int addTwoStatic(int i, int j){ return i+j; }
public static void main(String[] args){ addTwoStatic(11,12); }
|
2. Constant, Local Variable和Control Construct的使用
2.1 int类型变量的操作
void spin() { int i; for (i = 0; i < 100; i++) { } }
|
2.2 short类型变量操作
由于operand stack和local variable的实现原因, Java指令支持int的store, load, add操作(也因为int使用最为频繁). 但对于其他Integer(byte, char, short)就没有相应的指令, 例如:
void sspin() { short i; for (i = 0; i < 100; i++) { ; } }
|
2.3 double类型变量操作
由于缺乏byte, char和short的操作指令, 所以用int的指令代替. 但这并没有什么不妥, 只不过int操作会导致值的截断
对于long和float类型来说, 有store和load指令, 但没有比较指令. 下面只以double为例:
void dspin() { double i; for (i = 0.0; i < 100.0; i++) { ; } }
|
3. Arithmetic
JVM通常会在operand stack上做算术运算(iinc是个例外, 它直接针对local variable), 例如:
int align2grain(int i, int grain) { return ((i + grain-1) & ~(grain-1)); }
|
4. Run-time Constant Pool
4.1 -1 ~ 5
使用iconst_<i>
指令
4.2 -128 ~ 127
使用bipush
指令
int i1 = 127; int i2 = -128;
|
4.3 -32768 ~ 32767
使用sipush指令
int i1 = -32768; int i2 = 32767;
|
4.4 -2147483648 ~ 2147483647
使用ldc
指令
int i1 = -32769; int i2 = 32768;
|
4.5 long and double
如果分配0或1, 则用lconst_<l>
和dconst_<d>
long l1 = 0; long l2 = 1; long l3 = 2;
double d1 = 0.0; double d2 = 1.0; double d3 = 3.0;
|
5. 条件控制
5.1 int
void whileInt() { int i = 0; while (i < 100) { i++; }
|
5.2 float/double
对于float和double类型来说, 有两种对比方式
当遇到NaN时会做出不同的行为, 以下以double为例:
int lessThan100(double d) { if (d < 100.0) { return 1; } else { return -1; } }
|
5.3 break
void breakTest(int i) { while(i<10){ if(i>5) break; i++; } }
|
6. function parameter
非成员函数将参数从0开始添加, 成员函数从1开始添加
static int addTwo(int i, int j){ return i+j; }
public static void main(String[] args){ addTwo(1,2); }
|
7. Class Object
7.1 object as parameter
Test getTest() { Test t = new Test(); return processTest(t); }
static Test processTest(Test t) { if (t != null) return t; else return null; }
|
7.2 call member function
public class Test { int i = 1; void set(int i) { this.i = i; }
public static void main(String[] args){ Test t = new Test(); t.set(2); }
}
|
8. Array
8.1 one-dimensional array of primitive type
int buffer[]; buffer = new int[100]; int value = 12; buffer[10] = value; value = buffer[11];
|
8.2 one-dimensional array with of reference
Test buffer[]; buffer = new Test[100];
Test value = new Test(); buffer[10] = value; value = buffer[11];
|
8.3 multi-dimensional array
int buffer[][][]; buffer = new int[2][3][4];
int value = 10; buffer[1][1][1] = value; value = buffer[1][1][1];
|
9. switch
Java有两条指令来处理int类型的switch: tableswitch
和lookupswitch
. 如果数据类型为byte, char或short, 则先将类型提升至int然后再做处理. tableswitch针对连续case值, lookupswitch针对不连续case值:
9.1 table
int chooseNear(int i) { switch (i) { case 0: return 0; case 1: return 1; case 2: return 2; default: return -1; } }
|
9.2 lookupswitch
int chooseFar(int i) { switch (i) { case -10: return 0; case 10: return 1; case 20: return 2; default: return -1; } }
|
10. Member Variable
private long index = 0;
long nextIndex() { return index++; }
|
11. Declaring Member Variable
11.1 throw
当用athrow时, 则在exception_table中寻找这个objectref的handler, 如果找到对应的handler, pc重置到handler的位置, 并将frame的operand stack清空, objectref装入operand stack中.
如果没有handler, 则将当前frame弹出, 并将objectref抛给该frame的调用者.
int dosomething() throws ArithmeticException { int a =0, b = 1; if(a == 0){ throw new ArithmeticException(); } return b/a; }
|
11.2 catch
void dosomething() throws ArithmeticException { try { int a = 1 / 0; } catch (ArithmeticException e) { System.out.println("an error"); } }
|
11.3 finally
void dosomething() { int a = 1; int b = 3; try { b = a + b; } catch (RuntimeException e1) { b = a - b; } catch (Exception e2) { b = a * b; } finally { a = 0; } }
|