java代码初始化的作用 java代码初始化的作用是什么( 三 )


java.lang.Strings;
publicdebug.Test();
Code:
0:aload_0
1:invokespecial#1;//Methodjava/lang/Object."":()V
4:aload_0
5:iconst_0
6:putfield#2;//Fieldx:I
9:aload_0
10:ldc#3;//String123
12:putfield#4;//Fields:Ljava/lang/String;
15:ldc#5;//String456
17:astore_1
18:ldc#6;//String789
20:astore_1
21:return
publicstaticvoidmain(java.lang.String[]);
Code:
0:new#7;//classdebug/Test
3:dup
4:invokespecial#8;//Method"":()V
7:pop
8:return
}
如果在同一个类中 , 一个构造方法调用了另一个构造方法,那么对应的""方法就会调用另一
个"",但是实例变量和初始化块会被忽略,否则它们就会被多次执行 。
packagedebug;
publicclassTest{
Strings1=rt("s1");
Strings2="s2";
publicTest(){
s1="s1";
}
publicTest(Strings){
this();
if(1==1)thrownewRuntime();
}
Stringrt(Strings){
returns;
}
publicstaticvoidmain(String[]args){
newTest("");
}
}
反编译的结果:
Compiledfrom"Test.java"
publicclassdebug.Testextendsjava.lang.Object{
java.lang.Strings1;
java.lang.Strings2;
publicdebug.Test();
Code:
0:aload_0
1:invokespecial#1;//Methodjava/lang/Object."":()V
4:aload_0
5:aload_0
6:ldc#2;//Strings1
8:invokevirtual#3;//Methodrt:(Ljava/lang/String;)Ljava/lang/String;
11:putfield#4;//Fields1:Ljava/lang/String;
14:aload_0
15:ldc#5;//Strings2
17:putfield#6;//Fields2:Ljava/lang/String;
20:aload_0
21:ldc#2;//Strings1
23:putfield#4;//Fields1:Ljava/lang/String;
26:return
publicdebug.Test(java.lang.String);
Code:
0:aload_0
1:invokespecial#7;//Method"":()V
4:new#8;//classjava/lang/RuntimeException
7:dup
8:invokespecial#9;//Methodjava/lang/RuntimeException."":()V
11:athrow
java.lang.Stringrt(java.lang.String);
Code:
0:aload_1
1:areturn
publicstaticvoidmain(java.lang.String[]);
Code:
0:new#10;//classdebug/Test
3:dup
4:ldc#11;//String
6:invokespecial#12;//Method"":(Ljava/lang/String;)V
9:pop
10:return
}
我们再一次看到了javap实现的bug , 虽然有一个"":(Ljava/lang/String;)V签名可以说明
每个构造方法对应一个不同,但Runtime异常仍然被定位到了""()V的方法中:
invokespecial#8;//Methodjava/lang/RuntimeException."":()V,而在main方法中的
调用却明明是"":(Ljava/lang/String;)V.
但是我们看到,由于Test(Strings)调用了Test();所以"":(Ljava/lang/String;)V不再对
实例变量和初始化块进次初始化:
publicdebug.Test(java.lang.String);
Code:
0:aload_0
1:invokespecial#7;//Method"":()V
4:new#8;//classjava/lang/RuntimeException
7:dup
8:invokespecial#9;//Methodjava/lang/RuntimeException."":()V
11:athrow
而如果两个构造方法是相互独立的,则每个构造方法调用前都会执行实例变量和初始化块的调用:
packagedebug;
publicclassTest{
Strings1=rt("s1");
Strings2="s2";
{
Strings3="s3";
}
publicTest(){
s1="s1";
}
publicTest(Strings){
if(1==1)
thrownewRuntimeException();
}
Stringrt(Strings){
returns;
}
publicstaticvoidmain(String[]args){
newTest("");
}
}
反编译的结果:
Compiledfrom"Test.java"
publicclassdebug.Testextendsjava.lang.Object{
java.lang.Strings1;
java.lang.Strings2;
publicdebug.Test();
Code:
0:aload_0
1:invokespecial#1;//Methodjava/lang/Object."":()V
4:aload_0
5:aload_0
6:ldc#2;//Strings1

推荐阅读