一:默认构造
默认构造函数就是在没有显式提供初始化式时调用的构造函数。它由不带参数的构造函数,或者为所有的实参提供默认实参的构造函数定义。如果定义某个类的变量时没有提供初始化时就会使用默认构造函数。
public class Trangle {
public static void main(String[] args)
{
Foo obj1 = new Foo();
}
}
class Foo{
int value;
public Foo(int initValue)//自定义构造,导致系统不再提供默认的构造方法
{
value=initValue;
}
}
总结:代码错误,如果类提供了一个自定义的构造方法,导致系统不再提供默认构造方法。
二:如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
public class Trangle{
public static void main(String[] args)
{
InitializeBlockClass obj=new InitializeBlockClass();
System.out.println(obj.field);
obj=new InitializeBlockClass(300);
System.out.println(obj.field);
}
}
class InitializeBlockClass{
{
field=200;
}
public int field=100;
public InitializeBlockClass(int value)
{
this.field=value;
}
public InitializeBlockClass(){
}
}
总结:
1)所有类的变量都默认初始化null,数字类的原始数据类型默认初始化为0。
2)执行类成员定义的默认值或初始化块,优先于最新的那个,如上式的100。
3)执行类的构造函数,有多个构造函数,通过参数区分执行,创建类的对象时,就会立即执行。因此,适合于封装那些“对象创建时必须执行的代码”。
使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”。
public class Duixiang {
public static void main(String[] arge){
Information a=new Information();
a.OutputInformation();
Information b=new Information();
b.OutputInformation();
Information c=new Information();
c.OutputInformation();
Information d=new Information();
d.OutputInformation();
}
}
class Information{
static int num=0;
Information()
{
num++;
}
public void OutputInformation()
{
System.out.println("你已经创建了"+num+"个对象!");
}
}
创建子类对象会导致父类初始化块的执行顺序是:
先初始化父类(最高层次的)的静态初始化块,父类的无参构造器,在进行子类的静态初始化块,子类的无参构造器;
然后是父类的普通初始化块,子类的普通初始化块;父类的带参构造器,子类的带参构造器。
静态初始化块的执行顺序是:
先初始化父类(最高层次的)的静态初始化块,父类的无参构造器,在进行子类的静态初始化块,子类的无参构造器;
然后是父类的普通初始化块,子类的普通初始化块;父类的带参构造器,子类的带参构造器。
静态初始化块只执行一次。 创建子类型的对象时,也会导致父类型的静态初始化块的执行。