本文发表于本人博客。
之前都讲了有关字符串的陷阱,那今天来说下关于静态这个东西,这分为静态变量、静态方法,先看下面的代码请问结果输出是什么?:
class Person01{ private static Person01 person = new Person01(); public static int age; public static int hight = 0; private Person01(){ age++; hight++; } public static Person01 GetInstance(){ return person; } }
在main中进行调用
Person01 person = Person01.GetInstance();
System.out.println("age:" + person.age + ";hight:" + person.hight);
这 个有可能有工作1年2年的也没有说出正确的答案。这个题目考察的是静态变量初始化顺序,现在我们来分析下:当main函数中使用Person01 person = Person01.GetInstance();调用静态方法的时候,首先回去查找有静态变量存在不,如果存在则从上往下先执行,这里是从person, 在到age、hight,由于person是需要调用构造的所以这句完毕后age、hight都已经是为0了,再往下执行static变量,然而对于 age它只是申明并没有赋值操作,所以跳过了,再往下就是对hight赋值了,都完毕后则return person返回这个对象,所以输出是:
age:1;hight:0
如果还有怀疑可以把对age以及hight这2句放到person对象前面再执行查看结果,可以看到输出的结果是:
age:1;hight:1
至此你不相信总之我是信了!那接下来我们修改下代码,如下:
class Person01{ private static Person01 person = new Person01(10,100); public static int age; public static int hight = 0; private Person01(int age,int hight){ age = age; hight = hight; } public static Person01 GetInstance(){ return person; } }
上面代码跟之前的代码相比只是在new构造的时候传递参数了,请问现在输出又是什么?我估计这里有些人被打虎眼了,先看结果:
age:0;hight:0
为 什么呢?我们可以再new Person01(10,100)处开始说说,这里new构造传递了参数了,在构造函数中,age、以及hight2个变量是临时变量不是类 Person01的变量哦,所以这里的操作是改变这个构造函数方法内的变量的值而已,不会影响类的变量,这样结果可想而知了。大家这里可以想象如果使用 this关键字呢,结果如何?结果还是:
age:10;hight:0
上面的例子只是说了静态函数以及静态字段,现在我们来看看如果在继承子类父类都出现了构造以及静态代码库,那么这样的执行顺序是怎样的呢,看下面代码:
class Person{ static String name = "www.luoliang.me"; static{ System.out.println("Person"); } public Person(){ System.out.println("Person()"); } } class Man extends Person { static String name = "luoliang.me"; static{ System.out.println("Man"); } public Man(){ System.out.println("Man()"); } }
main方法中调用如下:
public static void main(String[] args) { new Man(); }
输出结果是什么呢,这个问题确实是TMD的,带了好多代码但是唯独这个静态代码快的基本没用,最后问朋友也没说对答案,看答案:
Person
Man
Person()
Man()
这个答案没有想到吧,不过想想又觉得是非常合符的,毕竟有静态代码的先执行静态代码,这个比构造函数优先级还高啊!这次先到这里,明天继续。