转载于 http://blog.csdn.net/cherishme1988/article/details/12095637
可见java基础还是很重要的,我 相信还是有很多人写错的,贴出来大家一起学习。
题目要求:输出运行结果:
- public class Text {
- public static int k =0 ;
- public static Text t1 = new Text("t1") ;
- public static Text t2 = new Text("t2") ;
- public static int i = print("i") ;
- public static int n =99 ;
- public int j = print("j") ;
- {
- print("构造块");
- }
- static {
- print("静态块");
- }
- public Text(String str){
- System.out.println((++k)+":"+str+" i="+i+" n="+n) ;
- ++i;++n ;
- }
- public static int print(String str){
- System.out.println((++k)+":"+str+" i="+i+" n="+n) ;
- ++n;
- return ++i ;
- }
- public static void main (String args[]){
- Text t = new Text("init") ;
- }
- }
运行结果如下:
1:j i=0 n=0 2:构造块 i=1 n=1 3:t1 i=2 n=2 4:j i=3 n=3 5:构造块 i=4 n=4 6:t2 i=5 n=5 7:i i=6 n=6 8:静态块 i=7 n=99 9:j i=8 n=100 10:构造块 i=9 n=101 11:init i=10 n=102 |
首先看到static关键字,脑子里面第一反应有几点,
1、公有属性,可以有类名称直接访问。
2、静态方法,可以有类名称直接方法。
3、静态方法或者属性,可以再对象实例化之前就调用
至于该题中,顺序执行,先执行public static int k =0 ;
因为没有输出不用考虑这个,接着public static Text t1 = new Text("t1") ;
在t1对象初始化时先执行非静态方法或者非静态常量,顺序执行,接着运行构造参数,
根据程序来看应该打印三条记录,分别是
1:j i=0 n=0 2:构造块 i=1 n=1 3:t1 i=2 n=2 |
接下来public static Text t2 = new Text("t2") ;同理,执行完之后继续执行static代码块或者赋值静态变量,在main()方法中new了一个新的实例,静态变量只执行一次,接下来就是顺序执行非静态方法---->构造方法。应该是这样的顺序,面试的时候我写的不完成,哎。
接着想到继承关系(extends)子类继承一个父类之后,对象初始化的顺序又是怎样?
我写了一个demo,大家共勉
- class A{
- public static int k = 0 ;
- static {
- System.out.println("父类静态方法") ;
- }
- {
- System.out.println("父类非静态方法") ;
- }
- public A(){
- System.out.println("父类构造");
- }
- }
- class B extends A{
- static {
- System.out.println("子类静态方法") ;
- }
- {
- System.out.println("子类非静态方法") ;
- }
- public B(){
- System.out.println("子类构造");
- }
- }
- public class Demo {
- public static void main(String args[]){
- B b = new B() ;
- }
- }
输入结果如下:
父类静态方法 子类静态方法 父类非静态方法 父类构造 子类非静态方法 子类构造 |
最后总结了几点:
- 1 /*
-
- 2 * 几大原则
-
- 3 * 一、静态成员变量(Static)
-
- 4 * 1、静态成员变量为类变量,所有对象共享同一内存空间
-
- 5 * 2、静态成员变量的声明和定义仅在首次加载类时执行一次
-
- 6 * 3、首次加载类时首先对所有静态成员变量根据类型默认赋初值,然后再对有右值的附右值
-
- 7 * 二、静态初始块
-
- 8 * 1、静态初始化块仅在首次加载类时执行一次
-
- 9 * ······多个静态成员变量与静态始化快参照出现顺序先后执行······
-
- 10 * 三、动态成员变量
-
- 11 * 1、动态成员变量定义在每次实例化对象时在构造函数之前执行
-
- 12 * 四、动态初始化块
-
- 13 * 1、动态初始化块在每次实例化对象时在构造函数之前执行
-
- 14 * ······多个动态成员变量与动态初始化块参照出现顺序先后执行······
-
- 15 * 总结:总的来说,在不涉及继承的前提下,当首次加载类时,按照如下顺序执行
-
- 16 * 1、按照出现顺序先后执行静态成员变量定义与静态初始化块
-
- 17 * 2、按照出现顺序先后执行动态成员变量定义与动态初始化块
-
- 18 * 3、执行构造函数
-
- 19 * 再次实例化对象时只执行第2、3步即可
-
- 20 *
-
- 21 * ············成员变量与定义与初始化块先于构造函数执行·········
-
- 22 * 五、当涉及到继承时,按照如下顺序执行
-
- 23 * 1、执行父类的静态成员变量定义与静态初始化块,执行子类的静态成员变量定义与静态初始化块
-
- 24 * 2、执行父类的非静态成员变量定义与动态初始化块,执行父类构造方法
-
- 25 * 3、执行子类的非静态成员变量定义与动态初始化块,执行子类构造方法
-
- 26 * 另:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在调用父类构造函数中使用子类重写的方法
总结了一点,不对之处还望多多指点,多谢。