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

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

时间: 2024-10-06 16:08:57

Java基础知识陷阱(三)的相关文章

Java基础知识陷阱系列

Java基础知识陷阱系列 今天抽空把Java基础知识陷阱有关的文章汇总于此,便于大家查看. Java基础知识陷阱(一) Java基础知识陷阱(二) Java基础知识陷阱(三) Java基础知识陷阱(四) Java基础知识陷阱(五) Java基础知识陷阱(六) Java基础知识陷阱(七) Java基础知识陷阱(八)

Java基础知识的三十个经典问答

Java基础知识的三十个经典问答 1.面向对象的特点 抽象: 抽象是或略一个主题中与当前目标的无关的因素,一边充分考虑有关的内容.抽象并不能解决目标中所有的问题,只能选择其中的一部分,忽略其他的部分.抽象包含两个方面:一是过程抽象:一是数据抽象. 继承 继承是一种联接类的层次模型,允许和鼓励类的重用,提供了一种明确的共性的方法.对象的一个新类可以从现有的类中派生,这叫做类的继承.心累继承了原始类 的特性,新类称为原始类的派生类或者是子类,原始类称为新类的基类或者父类.子类可以从父类那里继承父类的

Java基础知识陷阱(九)

本文发表于本人博客. 今天我来说说关于JAVA多线程知识,有错误请指出.大家都知道JAVA在服务端上处理也有很大优势,很多公司也有在服务器跑JAVA进程,这说明JAVA在处理这个多线程以及并发下也有一定有优点的(这说法有点坑了).下面来看看 那java中,不具备直接操作像操作系统一样的PV信号,然而它提供了synchronized来实现同步机制,可能这样说不够严谨.JAVA的基类Object中有以下几个方法: public final native void notify(); public f

Java基础知识陷阱(十)

上个星期由于时间比较紧所以未能继续写下去,今天再接再厉,专心 + 坚持这样离目标就越来越近了!废话少说说正题,今天我们还是来说说java中比较基础的知识,大家知道编写java程序中很多时候都用到了xml文件,有 些是框架本身支持配置的,有些是自定义配置的,这样就要求我们要对这个xml原理要比较了解,其中加载xml文件转换节点元素时有个核心:递归调用转换. 我们可以通过下面方法来查查这个实现类有关的源码: 1 2 3 4 DocumentBuilderFactory factory = Docum

Java基础知识 第三章 流程控制

一  流程控制结构 1.在java中,共有3种流程控制结构: (1)顺序结构:程序从上到下依次执行每条语句,中间没有任何的判断和跳转. (2)选择结构:根据条件判断的结果来选择执行不同的代码.根据细节的不同可分为单分支结构,双分支结构,多分支结构. (3)循环结构:根据条件来重复性地执行某段代码. 2.java 中提供了if控制语句,switch语句,来实现选择结构. (1)if控制语句 语法:if(条件){ 语句 } 条件必须是布尔值 (2)if-else语句:实现双分支处理 语法:if(条件

Java 基础知识总结 (三、运算符)

三.Operators 运算符 Assignment Operators(赋值运算符) =   +=   -=   %=   *=   /=    <<=     >>=     >>>=    &=    ^=      |= public class ByteDemo { public static void main(String[] args) { byte b1=2; byte b2=3; b1=(byte)(b1+b2); //加法,转int

Java基础知识陷阱(七)

本文发表于本人博客. 上次说了下HashSet和HashMap之间的关系,其中HashMap这个内部有这么一句: static final float DEFAULT_LOAD_FACTOR = 0.75f; 这一句表示一个常量,作用是当容器数量大小达到0.75%的时候就进行重新在构建一个2倍大小的数组.竟然这2个是集合,那我们今天看看其他的集合类,比如:ArrayList.Vector.LinkedList,开始咯. 首先查看下ArrayList的源码,这几个集合类都是在java.util包下

Java基础知识陷阱(四)

本文发表于本人博客. 今天我们来说说关于java继承以及反射有关的问题,大家先看下下面代码,试问可以编译通过不,为什么具体说说原因? public class Test{ public static void main(String[] args){ Person p = new Man(); p.talk(); } } class Person{ public void talk() throw NullPointerException{ System.out.println("Person

java基础知识(三)

1.abstract class Name {   private String name;   public abstract boolean isStupidName(String name) {}}大侠们,这有何错误?答案: 错.abstract method必须以分号结尾,且不带花括号.2.public class Something {   void doSomething () {       private String s = "";       int l = s.l