关于静态代码块,初始化块,与构造函数



        在学习Java基础期间,子父类的静态代码块、构造代码块、构造方法的执行顺序容易混淆,现在通过一段程序来说明它们的执行顺序。

一、先看一个简单的静态测试程序:


运行结果:

执行父类的静态代码块。
执行子类的静态代码块。
执行父类的构造代码块。
执行父类的不带参数的构造方法。
执行子类的构造代码块。
执行子类的不带参数的构造方法。

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
             
             
class FatherStaticTest
{
static
{
System . out . println ( "执行父类的静态代码块。" );
}
FatherStaticTest ()
{
System . out . println ( "执行父类的不带参数的构造方法。" );
}
FatherStaticTest ( int num )
{
System . out . println ( "执行父类的带参数的构造方法。" );
}
FatherStaticTest ( String str )
{
System . out . println ( "执行父类的带参数的构造方法。" );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行父类的构造代码块。" + sum );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行父类的构造代码块。" + sum );
}
{
int m = 3 ;
int n = 4 ;
int sum = ( m + n );
System . out . println ( "执行父类的构造代码块。" + sum );
}
}
class SonStaticTest extends FatherStaticTest
{
static
{
System . out . println ( "执行子类的静态代码块。" );
}
SonStaticTest ()
{
System . out . println ( "执行子类的不带参数的构造方法。" );
}
SonStaticTest ( int num )
{
super ( 7 );
System . out . println ( "执行子类的带参数的构造方法。" );
}
SonStaticTest ( String str )
{
super ( 7 );
System . out . println ( "执行子类的带参数的构造方法。" );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行子类的构造代码块。" + sum );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行子类的构造代码块。" + sum );
}
{
int m = 3 ;
int n = 4 ;
int sum = ( m + n );
System . out . println ( "执行子类的构造代码块。" + sum );
}
}
class StaticTest
{
public static void main ( String [] args )
{
new SonStaticTest ( "a" );
}
}
 来自CODE的代码片
StaticTest2.java


运行结果:

执行父类的静态代码块。
执行子类的静态代码块。
执行父类的构造代码块。3
执行父类的构造代码块。3
执行父类的构造代码块。7
执行父类的带参数的构造方法。
执行子类的构造代码块。3
执行子类的构造代码块。3
执行子类的构造代码块。7
执行子类的带参数的构造方法。



二、结论:

1、执行顺序:父类的静态代码块--->子类的静态代码块--->父类的构造代码块--->父类的构造方法--->子类的构造代码块--->子类的构造方法

2、静态代码块随类的加载而执行,只执行一次,优先于main方法,用于初始化整个类。

3构造代码块是给一个类的所有的对象进行初始化,可执行多次。只要对象一建立,就会调用构造代码块。构造代码块可以重复,可以有多份。

4构造方法是给与之对应的对象进行初始化,有针对性。构造方法要么带参数,要么不带参数。当类中没有显式的构造方法时,jvm会默认执行一个不带参数的构造方法。同一个类中不能出现两个或两个以上相同的构造方法(方法名和参数列表都相同)。

5、在子类的所有构造方法中如果没有显式的super语句,则默认第一条语句为隐式的super语句:super();会访问父类的不带参数的构造方法。当父类中只有带参数的构造方法时,子类必须用显式的带参数的super语句访问父类的构造方法。若显示的super语句不带参数,则编译失败。当父类中只有显式的不带参数的构造方法时,子类必须用显示的不带参数的super语句访问父类的构造方法。否则,编译失败。

6在创建子类的实例对象时未传入参数,若子类只有带参数的构造方法则编译失败。若子类有不带参数的构造方法,则执行子类的不带参数的构造方法。若子类没有构造方法,则执行隐式的不带参数的构造方法。

7、在创建子类的实例对象时传入参数:若子类有带参数的构造方法,则执行子类的带参数的构造方法;若子类没有带参数的构造方法或者没有构造方法,则编译失败。
        在学习Java基础期间,子父类的静态代码块、构造代码块、构造方法的执行顺序容易混淆,现在通过一段程序来说明它们的执行顺序。

一、先看一个简单的静态测试程序:


运行结果:

执行父类的静态代码块。
执行子类的静态代码块。
执行父类的构造代码块。
执行父类的不带参数的构造方法。
执行子类的构造代码块。
执行子类的不带参数的构造方法。

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
              
              
class FatherStaticTest
{
static
{
System . out . println ( "执行父类的静态代码块。" );
}
FatherStaticTest ()
{
System . out . println ( "执行父类的不带参数的构造方法。" );
}
FatherStaticTest ( int num )
{
System . out . println ( "执行父类的带参数的构造方法。" );
}
FatherStaticTest ( String str )
{
System . out . println ( "执行父类的带参数的构造方法。" );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行父类的构造代码块。" + sum );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行父类的构造代码块。" + sum );
}
{
int m = 3 ;
int n = 4 ;
int sum = ( m + n );
System . out . println ( "执行父类的构造代码块。" + sum );
}
}
class SonStaticTest extends FatherStaticTest
{
static
{
System . out . println ( "执行子类的静态代码块。" );
}
SonStaticTest ()
{
System . out . println ( "执行子类的不带参数的构造方法。" );
}
SonStaticTest ( int num )
{
super ( 7 );
System . out . println ( "执行子类的带参数的构造方法。" );
}
SonStaticTest ( String str )
{
super ( 7 );
System . out . println ( "执行子类的带参数的构造方法。" );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行子类的构造代码块。" + sum );
}
{
int i = 1 ;
int j = 2 ;
int sum = ( i + j );
System . out . println ( "执行子类的构造代码块。" + sum );
}
{
int m = 3 ;
int n = 4 ;
int sum = ( m + n );
System . out . println ( "执行子类的构造代码块。" + sum );
}
}
class StaticTest
{
public static void main ( String [] args )
{
new SonStaticTest ( "a" );
}
}
 来自CODE的代码片
StaticTest2.java


运行结果:

执行父类的静态代码块。
执行子类的静态代码块。
执行父类的构造代码块。3
执行父类的构造代码块。3
执行父类的构造代码块。7
执行父类的带参数的构造方法。
执行子类的构造代码块。3
执行子类的构造代码块。3
执行子类的构造代码块。7
执行子类的带参数的构造方法。



二、结论:

1、执行顺序:父类的静态代码块--->子类的静态代码块--->父类的构造代码块--->父类的构造方法--->子类的构造代码块--->子类的构造方法

2、静态代码块随类的加载而执行,只执行一次,优先于main方法,用于初始化整个类。

3构造代码块是给一个类的所有的对象进行初始化,可执行多次。只要对象一建立,就会调用构造代码块。构造代码块可以重复,可以有多份。

4构造方法是给与之对应的对象进行初始化,有针对性。构造方法要么带参数,要么不带参数。当类中没有显式的构造方法时,jvm会默认执行一个不带参数的构造方法。同一个类中不能出现两个或两个以上相同的构造方法(方法名和参数列表都相同)。

5、在子类的所有构造方法中如果没有显式的super语句,则默认第一条语句为隐式的super语句:super();会访问父类的不带参数的构造方法。当父类中只有带参数的构造方法时,子类必须用显式的带参数的super语句访问父类的构造方法。若显示的super语句不带参数,则编译失败。当父类中只有显式的不带参数的构造方法时,子类必须用显示的不带参数的super语句访问父类的构造方法。否则,编译失败。

6在创建子类的实例对象时未传入参数,若子类只有带参数的构造方法则编译失败。若子类有不带参数的构造方法,则执行子类的不带参数的构造方法。若子类没有构造方法,则执行隐式的不带参数的构造方法。

7、在创建子类的实例对象时传入参数:若子类有带参数的构造方法,则执行子类的带参数的构造方法;若子类没有带参数的构造方法或者没有构造方法,则编译失败。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值