深入理解Java初始化的含义

下面我们再来看看实例初始化方法""

  ""用于对象创建时对对象进行初始化,当在HEAP中创建对象时,一旦在HEAP分配了空间。最先就会调用""方法。这个方法包括实例变量的赋值(声明不在其中)和初始化块,以及构造方法调用。如果有多个重载的构造方法,每个构造方法都会有一个对应的""方法。构造方法隐式或显示调用父类的构造方法前,总是先执行实例变量初始化和初始化块.同样,实例变量和初始化块的顺序也是按源文件的原文顺序执行,构造方法中的代码在最后执行:

package debug;
public class Test {
 int x = 0;
 String s = "123";
 {
  String s1 = "456";
  //if(1==1)
  //throw new RuntimeException();
 }
 public Test(){
  String ss = "789";
 }
 public static void main(String[] args) {
  new Test(); 数据挖掘工具
 }
}
javap -c debug.Test的结果:
 Compiled from "Test.java"
 public class debug.Test extends java.lang.Object{
  int x;
  java.lang.String s;
  public debug.Test();
  Code:
  0: aload_0
  1: invokespecial #1; //Method java/lang/Object."":()V
  4: aload_0
  5: iconst_0
  6: putfield #2; //Field x:I
  9: aload_0
  10: ldc #3; //String 123
  12: putfield #4; //Field s:Ljava/lang/String;
  15: ldc #5; //String 456
  17: astore_1
  18: ldc #6; //String 789
  20: astore_1
  21: return
  public static void main(java.lang.String[]);
  Code:
  0: new #7; //class debug/Test
  3: dup
  4: invokespecial #8; //Method "":()V
  7: pop
  8: return
 }


  如果在同一个类中,一个构造方法调用了另一个构造方法,那么对应的""方法就会调用另一个"",但是实例变量和初始化块会被忽略,否则它们就会被多次执行。 数据挖掘实验室

package debug;
public class Test {
 String s1 = rt("s1");
 String s2 = "s2";
 public Test(){
  s1 = "s1";
 }
public Test(String s){
 this();
 if(1==1) throw new Runtime();
}
String rt(String s){
 return s;
}
public static void main(String[] args) {
 new Test("");
}
}

  反编译的结果:

Compiled from "Test.java"
public class debug.Test extends java.lang.Object{
 java.lang.String s1;
 java.lang.String s2;
 public debug.Test();
 Code:
 0: aload_0
 1: invokespecial #1; //Method java/lang/Object."":()V
 4: aload_0
 5: aload_0
 6: ldc #2; //String s1
 8: invokevirtual #3; //Method rt:(Ljava/lang/String;)Ljava/lang/String;
 11: putfield #4; //Field s1:Ljava/lang/String;
 14: aload_0
 15: ldc #5; //String s2
 17: putfield #6; //Field s2:Ljava/lang/String;
 20: aload_0
 21: ldc #2; //String s1
 23: putfield #4; //Field s1:Ljava/lang/String;
 26: return
 public debug.Test(java.lang.String);
 Code:
  0: aload_0
  1: invokespecial #7; //Method "":()V
  4: new #8; //class java/lang/RuntimeException
  7: dup
  8: invokespecial #9; //Method java/lang/RuntimeException."":()V
  11: athrow
  java.lang.String rt(java.lang.String);
 Code:
  0: aload_1
  1: areturn
  public static void main(java.lang.String[]);
 Code:
  0: new #10; //class debug/Test
  3: dup
  4: ldc #11; //String
  6: invokespecial #12; //Method "":(Ljava/lang/String;)V

数据挖掘论坛


  9: pop
  10: return
 }

  我们看到,由于Test(String s)调用了Test();所以"":(Ljava/lang/String;)V不再对实例变量和初始化块进次初始化:

public debug.Test(java.lang.String);
Code:
 0: aload_0
 1: invokespecial #7; //Method "":()V
 4: new #8; //class java/lang/RuntimeException
 7: dup
 8: invokespecial #9; //Method java/lang/RuntimeException."":()V
 11: athrow

  而如果两个构造方法是相互独立的,则每个构造方法调用前都会执行实例变量和初始化块的调用:

package debug;
public class Test {
 String s1 = rt("s1");
 String s2 = "s2"; 数据挖掘实验室
 {
  String s3 = "s3";
 }
public Test() {
 s1 = "s1";
}
public Test(String s) {
 if (1 == 1)
  throw new RuntimeException();
}
String rt(String s) {
 return s;
}
public static void main(String[] args) {
 new Test("");
}
}

  反编译的结果:

Compiled from "Test.java"
 public class debug.Test extends java.lang.Object{
  java.lang.String s1;
  java.lang.String s2;
  public debug.Test();
  Code:
  0: aload_0
  1: invokespecial #1; //Method java/lang/Object."":()V
  4: aload_0
  5: aload_0
  6: ldc #2; //String s1
  8: invokevirtual #3; //Method rt:(Ljava/lang/String;)Ljava/lang/String;
  11: putfield #4; //Field s1:Ljava/lang/String; 数据挖掘论坛
  14: aload_0
  15: ldc #5; //String s2
  17: putfield #6; //Field s2:Ljava/lang/String;
  20: ldc #7; //String s3
  22: astore_1
  23: aload_0
  24: ldc #2; //String s1
  26: putfield #4; //Field s1:Ljava/lang/String;
  29: return
  public debug.Test(java.lang.String);
  Code:
  0: aload_0
  1: invokespecial #1; //Method java/lang/Object."":()V
  4: aload_0
  5: aload_0
  6: ldc #2; //String s1
  8: invokevirtual #3; //Method rt:(Ljava/lang/String;)Ljava/lang/String;
  11: putfield #4; //Field s1:Ljava/lang/String;
  14: aload_0
  15: ldc #5; //String s2
  17: putfield #6; //Field s2:Ljava/lang/String;
  20: ldc #7; //String s3
  22: astore_2
  23: new #8; //class java/lang/RuntimeException
  26: dup
  27: invokespecial #9; //Method java/lang/RuntimeException."":()V
  30: athrow
  java.lang.String rt(java.lang.String); 数据挖掘论坛
  Code:
  0: aload_1
  1: areturn
  public static void main(java.lang.String[]);
  Code:
  0: new #10; //class debug/Test
  3: dup
  4: ldc #11; //String
  6: invokespecial #12; //Method "":(Ljava/lang/String;)V
  9: pop
  10: return
 }

  明白了上面这些知识,我们来做一个小测试吧:

public class Test2 extends Test1
{
 System.out.print("1");
}
Test2(){
 System.out.print("2");
}
static{
 System.out.print("3");
}
{
 System.out.print("4");
}
public static void main(String[] args) {
 new Test2();
}
}
class Test1 {
 Test1(){
 System.out.print("5");
}
static{
 System.out.print("6"); 数据挖掘工具
}
}

  试试看能清楚打印的顺序吗?如果没有new Test2()将打印什么?

[数据挖掘专家] [数据挖掘研究院] [数据挖掘论坛] [数据挖掘实验室]
上一篇:深入理解Java初始化的含义
下一篇:Ajax即时实现服务端数据验证
最新评论共有 0 位网友发表了评论 , 查看所有评论
发表评论( 不能超过250字,需审核,请自觉遵守互联网相关政策法规。 )
匿名?
数据挖掘网站导航 数据挖掘论坛导航
  • 数据挖掘工具
  • 数据挖掘论坛
  • DataCruncher - Cognos
  • MineSet - MathSoft
  • Intelligent Miner - GainSmarts
  • Sqlserver - SAS - Clementine
  • CART - Weka - WizSoft
  • NeuroShell - ModelQuest
  • data mining tools - Darwin
  • 数据挖掘交友
  • 数据挖掘博客
  • 数据挖掘工具
  • 数据挖掘资源
  • 数据挖掘技术算法
  • 数据挖掘相关期刊、会议
  • 研究院联盟合作专区
  • 数据挖掘基础与相关技术
  • 数据挖掘厂商与就业
  • 数据挖掘研究者乐园
  • 知名厂商数据挖掘工具资料
  • 国内数据挖掘实验室
  • Foreign Data Mining Lab
  • 热点关注
  • 阿蒙:一个程序员老总的年终总结
  • HTML框架代码全集
  • JAVA字符集
  • 即将消逝的十大热门技术 Java也算
  • 统一建模语言(UML)的现状及发展
  • UML的三大“硬伤”
  • AJAX 常用函数
  • UML用例建模的慨念和应用
  • AJAX通用类:AJAXRequest v0.3
  • 服务器端可控情形JS跨域访问解决方法
  • 论坛最新话题
  • Foundations of Statistical Natural Langu
  • Game Theory meet Data Mining: A Recent P
  • System Building: How does it help or hin
  • 数据挖掘与Clementine培训
  • 新手报到
  • 求 SASEM 客户流失预测分析
  • 数据挖掘工程师/搜索研究院—北京——无线
  • 数据挖掘入门介绍(如何着手数据挖掘)
  • Information Overload Survey Results
  • The INEX 2005 Workshop on Element Retrie
  • 相关资讯
  • Rational Rose和UML可视化建模基础
  • 系统约定:用UML描述工作流管理
  • UML的三大“硬伤”
  • 统一建模语言UML释义之(三)
  • 绘制UML活动图的步骤和要点
  • UML用例建模的慨念和应用
  • 用Rational Rose给XML DTD造型
  • 统一建模语言(UML)的现状及发展
  • 统一建模语言UML释义(二)
  • 统一建模语言UML概述
  • 数据挖掘实验室资料
  • 数据挖掘博客地址
  • 数据挖掘实验室网站地址
  • Prepare for Medicare audits by using dat
  • 注册成为SAS用户与爱好者俱乐部会员
  • 水南梅
  • 明日烟
  • 新人报道
  • 下载
  • 厦门服务器托管,450元/月—0592-5177319 高
  • 买空间送域名--0592-5177319 高静