• Java基础知识陷阱(三)


    本文发表于本人博客

        之前都讲了有关字符串的陷阱,那今天来说下关于静态这个东西,这分为静态变量、静态方法,先看下面的代码请问结果输出是什么?:

    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()

    这个答案没有想到吧,不过想想又觉得是非常合符的,毕竟有静态代码的先执行静态代码,这个比构造函数优先级还高啊!这次先到这里,明天继续。

  • 相关阅读:
    如何改变常用编辑器(eclipse)的字号大小
    IOConsole Updater error
    RNAfold的使用方法
    单因素方差分析(oneway ANOVA)
    Perl内部保留变量(系统变量)
    Perl 中的正则表达式
    Perl Eclipse 格式化代码
    卸载Oracle 9i
    Ubuntu的菜鸟常用的基础命令
    linux as4u2 下安装openssh
  • 原文地址:https://www.cnblogs.com/luoliang/p/4147156.html
Copyright © 2020-2023  润新知