深入理解final变量的初始化

 更新时间:2013年06月04日 16:47:21   作者:  
本篇文章是对final变量的初始化进行了详细的分析介绍,需要的朋友参考下
final变量的初始化位置 
一是其定义处,也就是说在final变量定义时直接给其赋值,
二是在构造函数中。而且在Java1.1以前,只能是在定义时给值。
三是在初如化代码块中{} 或者 static{}
复制代码 代码如下:

public class InitOrder {
    {
        System.out.println("before---field");
        //System.out.println("d1="+d1);
        d1 = 3;
        //System.out.println("d1="+d1);
    }
    static {
        System.out.println("before---static field");
        //System.out.println("d2="+d2);
        d2 = 3;
        //System.out.println("d2="+d2);
    }
    final int a1 = 1;
    final int b1;
    final int c1;
    final int d1;
    //final int e1;
    static final int a2 = 1;
    //static final int b2;
    static final int c2;
    static final int d2;
    //static final int e2;

    {
        System.out.println("after---field");
        //System.out.println("c1="+c1);
        c1 = 4;
        System.out.println("c1="+c1);
        //e2 =3;
    }
    static {
        System.out.println("after---static field");
        //System.out.println("c2="+c2);
        c2 = 4;
        System.out.println("c2="+c2);
        //e1 = 3;
    }
    public InitOrder() {
        b1 = 2;
        //b2 = 2;
    }
    public static void main(String[] args) {
        InitOrder order = new InitOrder();
        System.out.println("c1="+order.c1);
        System.out.println("c2="+order.c2);
        System.out.println("d1="+order.d1);
        System.out.println("d2="+order.d2);
    }
}

说明:上述所有注释皆为有语法错误
输出结果:
before---static field
after---static field
c2=4
before---field
after---field
c1=4
c1=4
c2=4
d1=3
d2=3
结果分析:
1. 对比a1,a2基本没有什么问题,定义时就初始化
2. 对比b1,b2在构造函数中初始化,b1没有问题,b2有问题,这是因为构造函数的调用在静态变量的后面而b2是静态的,所以会报错
3. 对比c1,d1发现初始化没有问题,有问题的是使用输出语句。对于d1在初始化代码块中不论在哪加输出语句都会报错,这是因为d1所在的初始化代码块位置在变量d1定义的前面,而java中变量的初始化顺序是见Java中变量的初始化顺序, 普通变量和初始化代码块的初始化顺序是按照位置的先后的所以输出用到了d1变量,所以出错,但有一点我不明白,为什么在这里初始化d1不报错,而且在main函数中还可以调用它,难道这个也要去看一下java虚拟机?对于c1在后面加输出语句没有问题。前面加有问题很好理解,就是大之前没有被初始化.
4. 对于c2,d2是和3同样的道理
5. 对于e1放在静态代码块中显然不行,因为静态代码块最先加载,那时e1还没有加
6. 对于e2也是,普通代码块的加载要晚于静态变量,所以也是不行的。

相关文章

  • java代码实现双向链表

    java代码实现双向链表

    这篇文章主要为大家详细介绍了java代码实现双向链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java CGLib动态代理机制(全面解析)

    Java CGLib动态代理机制(全面解析)

    下面小编就为大家带来一篇Java CGLib动态代理机制(全面解析)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Mybatis插入语句默认值不生效的问题及解决

    Mybatis插入语句默认值不生效的问题及解决

    这篇文章主要介绍了Mybatis插入语句默认值不生效的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 【面试】Spring事务面试考点吐血整理(建议珍藏)

    【面试】Spring事务面试考点吐血整理(建议珍藏)

    本文是小编给大家收藏整理的Spring事务面试考点,非常不错,值得收藏,感兴趣的朋友参考下吧
    2019-04-04
  • java面向对象之学生信息管理系统

    java面向对象之学生信息管理系统

    这篇文章主要为大家详细介绍了java面向对象之学生信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Java(springboot) 读取txt文本内容代码实例

    Java(springboot) 读取txt文本内容代码实例

    这篇文章主要介绍了Java(springboot) 读取txt文本内容代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java常见基本数据结构概览

    Java常见基本数据结构概览

    这篇文章主要介绍了Java常见的几种基本数据结构,包括其含义和用法,,需要的朋友可以参考下
    2017-09-09
  • 详解Mybatis-plus中更新date类型数据遇到的坑

    详解Mybatis-plus中更新date类型数据遇到的坑

    这篇文章主要介绍了详解Mybatis-plus中更新date类型数据遇到的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Spring DI依赖注入过程解析

    Spring DI依赖注入过程解析

    依赖注入是由“依赖”和“注入”两个词汇组合而成,那么我们再一次顺藤摸瓜,分别分析这两个词语,这篇文章主要介绍了Spring DI依赖注入详解,需要的朋友可以参考下
    2022-11-11
  • Java实现单链表SingleLinkedList增删改查及反转 逆序等

    Java实现单链表SingleLinkedList增删改查及反转 逆序等

    单链表是链表的其中一种基本结构。一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。 因为只有一个指针结点,称为单链表
    2021-10-10

最新评论