关于java对象初始化的一点有意思的东西

原创 2015年04月01日 08:46:52

这篇文章实际的内容并没有多少,或者说对实际编程影响并不大,主要是为了可能的笔试面试之类的,还有就是有点好玩而已。

有一天我在书上看到很有意思的代码:

class A{

    {
        System.out.println("----->A的初始化块");
    }

    static {
        System.out.println("----->A的静态初始化块");
    }

    public A(){
        System.out.println("----->A的构造器");
    }
}

class B extends A{
    {
        System.out.println("---->B的初始化块");
    }

    static {
        System.out.println("---->B的静态初始化块");
    }

    public B(){
        System.out.println("---->B的构造器");
    }
}

class C extends B{
    {
        System.out.println("--->C的初始化块");
    }

    static {
        System.out.println("--->C的静态初始化块");
    }

    public C(){
        System.out.println("--->C的构造器");
    }
}

public class ForBlogTest {
    public static void main(String[] args) {
        C c = new C();
        System.out.println("----------------------------------分割线----------------------------------");
        C c1 = new C();
    }
}

你假如已经知道他的输出了,那么可以不用看这篇文章了。以下是他的输出结果。

下面我就来解释以下,当然这是建立在我对jvm还没有深入了解的基础上讨论的,相信不就后,我会站在那个角度来对他进行解释。

首先输出的是A的静态初始块,为什么,我们可以把这个问题分解为两个。1,为什么输出静态初始块; 2,为什么先输出A 。

我们先来说说第一个问题:因为在我们new 一个变量时,编译器首先会各种方式找到你调用的类,然后对它进行加载。因为静态的变量,方法,初始块都属于类,所以在加载一个类时,也会加载属于他的初始块,方法,和变量。所以,我们第一个输出的是初始块,但为什么又只输出一次呢。因为在我们的内存中已经加载了该类,所以下一次new一个新对象时,根本不需要再重新加载,因此也就只掉用一次初始块了。

那第二个问题呢:因为在初始一个对对象的时候,编译器会先找到它的父类,并先调用他的初始化操作,所以可以得到,每次初始一个对象是,最先调用的是Object的初始化操作。

那么又为什么是先输出初始块呢。因为编译器会在生成class文件中将初始块里的代码加到所调用的构造器的器中,并在最前面。所以,我们总能看到初始块里的代码是先于构造器中的代码输出的。到这,这个例子也就理解差不多了。那我们再来看个东西

class D{
    private int num = 3;
    
    public D(){
        num = 4;
    }
    
    public int getNum(){
        return num;
    }
    
}
调用getNum(),将会得到什么呢。没错就是4。其实假如再加一段代码,我们就可以把它和上面所说的联系起来了。

class D{
    private int num = 3;

    {
        num = 4;
    }

    public D(){
    }

    public int getNum(){
        return num;
    }

}

你觉得这个会输出什么呢。的确,是4.那么当我们这样写呢。

class D{
    {
        num = 4;
    }
    
    private int num = 3;

    public D(){
    }

    public int getNum(){
        return num;
    }

}

num的值就变成了3。所以我们可以得出结论。其实在类中初始化的变量的优先级和初始块了初始化变量的优先级是一样的。因此,不难理解初始块里的代码为什么先于构造器中的输出了。好了,还不够,还有点有意思的东西。

class E{
    public E(){
        echo();
    }

    public void echo() {
        System.out.println("-------->这是父类中的echo");
    }
}

class F extends E{
    public void echo(){
        System.out.println("----->这是子类中的echo");
    }
}

public class ForBlogTest{
    public static void main(String[] args) {
        F f = new F();
    }
}
请问,这会输出什么。

答案是:----->这是子类中的echo

是不是感觉挺好玩的。在编译过程中什么事都是按照平常的进行。当时在运行时,子类的方法直接将父类的覆盖了,所以就输出了子类echo中的内容。这个原理就有点类似于

class E{
    public void echo() {
        System.out.println("-------->这是父类中的echo");
    }
}

class F extends E{
    public void echo(){
        System.out.println("----->这是子类中的echo");
    }
    public void test(){
        
    }
}

public class ForBlogTest{
    public static void main(String[] args) {
        E f = new F();
        f.echo();
    }
}

这个echo是输出子类中echo里的代码,但是,我们调用f.test();时,连编译器都不能通过。但是强制类型转化后又能调用,说明在运行时,内存中加载的的确是F中的方法和变量。


相关文章推荐

发现一个很有意思的小技巧:初始化有序常量的一点小技巧

转自:初始化有序常量的一点小技巧 编写程序有时会用到有序常量。一个常见的情况是对命令行参数进行处理,如下的代码片段:   public class A { ...

Java开发需要的一点东西

  • 2011年04月12日 19:47
  • 6.81MB
  • 下载

JAVA的一点东西。Java

  • 2010年05月27日 11:51
  • 14KB
  • 下载

JAVA web中的一点东西

参考文献: http://m.blog.csdn.net/article/details?id=45151569 http://www.cnblogs.com/goody9807/archive/...

Java面向对象程序设计中很重要的一些东西

面向对象具有多方面的吸引力。对于管理人员,它实现了更快和更廉价的开发与维护过程。对于分析与设计人员,能生成清晰、易于维护的设计方案。对于程序开发人员,对象的理解又是如此浅显。此外,面向对象的工具以及类...
  • wuha0
  • wuha0
  • 2012年01月29日 17:37
  • 498

有意思的东西:多维数组、矩阵与宇宙模型

数组,在编程中一种非常有用并且非常重要的概念。一般书上在介绍数组时只介绍一维数组和二维数组的应用,一般很少讲到三维数组,因为一般书上把三维和三维以上的数组定义成为多维数组,是可以按二维数组概念的处理方...
  • KimboQi
  • KimboQi
  • 2012年05月11日 13:38
  • 661

CSAPP中一个有意思的小东西

关于编译器优化数组操作的一个小东西

关于树状数组一些有意思的东西

嘛~最近刚刚学会树状数组,写个blog记录一下心得。树状数组呢,核心是一个叫lowbit的东西,lowbit(x)=x&-x=x的最后一位1的大小。 一、一个经典问题 一个初始值为0的k位计数器...

有意思的小东西

下图是今年Best of Show(最佳秀场)奖得主的代码,看上去是一个卡通女孩,实际上则是一个能够处理三种文件格式(PGM、PPM和ASCII Art)的降采样工具,厉害吧。作者是位在Google工...
  • jimzhai
  • jimzhai
  • 2012年04月27日 12:34
  • 507

sql端口修改方法,一点小东西

  • 2009年07月05日 22:45
  • 142B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于java对象初始化的一点有意思的东西
举报原因:
原因补充:

(最多只允许输入30个字)