java静态变量需要初始化吗_» Java静态变量初始化顺序浅谈
Java 类初始化顺序在网上已经有很多文章了,这里不再谈那么多,仅仅谈下Java静态变量的初始化顺序,如果你是Java高手,并且自认为对这个顺序已经掌握到了炉火纯青的境界,请忽视这篇文章.
前天看了Y.BOY对AS程序员的《关于初始化静态变量的一些思考》,让我感觉这个东西很奇妙,他的问题也是从JAVA来的.然后我就做了些测试,发现与我想的很不一样.而且Java与AS的也不一样.今天就先将关于Java的记录下来.等日后再将AS的也记录下来。
简单规则
首先先看一段最普遍的JAVA代码:
/**
* Java 测试代码
* Power by http://www.litefeel.com
* @author lite3
*/
public class Test
{
public static Test1 t = new Test1();
public static int a = 0;
public static int b;
public static void main(String[] arg)
{
System.out.println(Test.a);
System.out.println(Test.b);
}
}
class Test1
{
public Test1()
{
Test.a++;
Test.b++;
}
}
这里先猜下控制台输出结果是什么?
OK, 或许你已经猜到下面了结果了,那么你还是熟悉Java的。
0 1
如果你不明白是为什么会输出上面的结果,那么我来告诉你。
Java静态变量初始化遵循以下规则:
静态变量会按照声明的顺序先依次声明并设置为该类型的默认值,但不赋值为初始化的值。
声明完毕后,再按声明的顺序依次设置为初始化的值,如果没有初始化的值就跳过。
看了这个就会明白,原来Test.a的值变化了三次。
声明时设置为0>>Test1::Test1里设置为1>>Test.a初始化为0
复杂规则
明白了这个,请再看下面的代码。
/**
* Java 测试代码
* Power by http://www.litefeel.com
* @author lite3
*/
public class A
{
public static int b = B.a;
public static A plus =new A("A");
public static final int finalInt = (int)(Math.random()*100);
public static B p = new B("A");
public static final String finalStr = "finalStr";
public static final Integer finalInteger = new Integer(10);
public static int a = 1;
public static B c = null;
public A(String from)
{
System.out.println("----------- begin A::A ----------------");
System.out.println("A::A, from="+from);
System.out.println("A::A, A.b="+A.b);
System.out.println("A::A, A.finalInt="+A.finalInt);
System.out.println("A::A, B.a="+B.a);
System.out.println("A::A, B.plus="+B.plus);
System.out.println("----------- end A::A ----------------");
}
public static void main(String[] arg)
{
System.out.println("main, A.b="+A.b);
System.out.println("main, B.t="+B.t);
System.out.println("main, C.a="+C.a);
}
}
class B
{
public static int t = A.a;
public static A plus = new A("B");
public static int a = 1;
public B(String from)
{
System.out.println("----------- begin B::B ----------------");
System.out.println("B::B, from="+from);
System.out.println("B::B, B.a="+B.a);
System.out.println("B::B, A.a="+A.a);
System.out.println("B::B, A.p="+A.p);
System.out.println("B::B, A.plus="+A.plus);
System.out.println("B::B, A.finalInt="+A.finalInt);
System.out.println("B::B, A.finalInteger="+A.finalInteger);
System.out.println("B::B, A.finalStr="+A.finalStr);
System.out.println("----------- end B::B ----------------");
}
}
class C
{
public static final A a = new A("C");
}
这个你还能猜到输出结果吗? 我是在一边测试一边写的,所以我没猜出来.哈哈
控制台输出结果为:
----------- begin A::A ----------------
A::A, from=B
A::A, A.b=0
A::A, A.finalInt=0
A::A, B.a=0
A::A, B.plus=null
----------- end A::A ----------------
----------- begin A::A ----------------
A::A, from=A
A::A, A.b=1
A::A, A.finalInt=0
A::A, B.a=1
A::A, B.plus=A@a90653
----------- end A::A ----------------
----------- begin B::B ----------------
B::B, from=A
B::B, B.a=1
B::B, A.a=0
B::B, A.p=null
B::B, A.plus=A@1fb8ee3
B::B, A.finalInt=61
B::B, A.finalInteger=null
B::B, A.finalStr=finalStr
----------- end B::B ----------------
main, A.b=1
main, B.t=0
----------- begin A::A ----------------
A::A, from=C
A::A, A.b=1
A::A, A.finalInt=61
A::A, B.a=1
A::A, B.plus=A@a90653
----------- end A::A ----------------
main, C.a=A@61de33
这个结果你没猜到吧,哈哈.
要一句一句的讲解程序执行结果,还是要很到的篇幅的.这里就直接写出Java静态变量初始化遵循的规则了。
第一段的规则依然有效,只是不健全。
只有主动请求一个类,这个类才会初始化,仅包含静态变量,函数,等静态的东西.
继承关系时,先初始化父类,后初始化子类.
静态变量会按照声明的顺序先依次声明并设置为该类型的默认值,但不赋值为初始化的值.
声明完毕后,再按声明的顺序依次设置为初始化的值,如果没有初始化的值就跳过.
当初始化A.b=B.a时,暂停初始化A.b,设置当前类为B,跳到步骤3,并执行.
当初始化B.plus = new A时,暂停初始化B.plus,实例化A并赋值给B.plus.
当A的构造函数里需要获得B.a的值时,B.a还初始化并处于暂停初始化状态,直接取B.a的当前值,不再等待B.a初始化.
final,静态常量其实是遵循普通静态变量的初始化的,但是在编译时,编译器会将不可变的常量值在使用的地方替换掉.可以用Java反编译工具查看.
何为主动请求一个类
主动请求一个类,有以下6种方式:
调用类A的静态变量.
实例化类A, 即 new A.
继承类A.
使用反射的方式获取类A.
类A是程序的入口类(即main函数所在的类)
如果仅仅是声明类型为类A的变量,但不初始化,那么不是主动请求类A,也不会初始化类A.
以上仅仅是个人的一些看法,如果不正确的地方,希望能够被指正,也好共同进步.
java静态变量需要初始化吗_» Java静态变量初始化顺序浅谈相关推荐
- gmm中隐变量是什么的_机器学习-隐变量模型和期望最大算法
目录 1 隐变量模型 1.1 隐变量模型意义 1.2 高斯混合模型 GMM 1.3 其他模型(应用) 2 期望最大算法(EM) 2.1 EM算法意义 2.2 EM算法推导 2.3 EM算法 2.4 E ...
- mysql 多租户_数据层的多租户浅谈
数据层的多租户浅谈 刘 盛彬, 任 乐天, 和 陈 争云 2013 年 12 月 26 日发布 在上一篇"浅析多租户在 Java 平台和某些 PaaS 上的实现"中我们谈到了应用层 ...
- 单片机sleep函数的头文件_单片机代码模块化设计思想浅谈
前言:前段时间分享的文章[单片机裸机代码框架设计思路],很多读者给我留言,觉得很不错,对于初学者而言,这是一个进阶的技巧,对于我而言,这是对自己总结和表达能力的一个提升. 本文章我们再谈谈单片机代码的 ...
- 乐学python怎么样_铁乐学Python_day07_集合and浅谈深浅copy
1.[List补充] 在循环一个列表时,最好不要使用元素和索引进行删除操作,一旦删除,索引会随之改变,容易出错. 如果想不出错,可以采用倒着删除的方法,因为倒着删除进行的话,只是后面元素的位置发生了变 ...
- java技术的核心是哪个_[JAVA]《Java 核心技术》(一)
1. unicode编码表 utf-8和unicode的互换问题 2. subString(a,b) 获得 [a,b-1]的子串 3. 易犯错误,java没有引用传递 4. == 比较 ...
- java关于泛型的实验代码_[ Java学习 ] 泛型类的应用实验
成文原因: 这篇文章是我这周所做的 Java 实验题的一个小总结. 这次实验让我深刻赞同了我们 Java 老师在这节实验课前告诉我们的话: 最重要的是把问题想明白,它要怎么拆分成几个类,每个类里究竟需 ...
- java抓取网页标题内容_[Java教程]java 网页页面抓取标题和正文
[Java教程]java 网页页面抓取标题和正文 0 2014-07-10 09:01:30 import java.io.BufferedReader;import java.io.IOExcept ...
- Java格式化日期用斜杠_[java工具类01]__构建格式化输出日期和时间的工具类
在之前的学习中,我写过一篇关于字符串格式化的,就主要设计到了时间以及日期的各种格式化显示的设置,其主要时通过String类的fomat()方法实现的. 我们可以通过使用不同的转换符来实现格式化显示不同 ...
- java期末判断题题库_(java期末考试选择题题库.doc
(java期末考试选择题题库 1.分析以下程序: 1)public class x{ 2)public static void main(String[]args){ 3)String ol=new ...
最新文章
- android level list,Android Drawable (levle List selector layer List)
- Python进阶之一
- VII Python(9)socket编程
- 如何设计一门语言(九)——类型
- 30、自定义gridview
- poj2975——Caesar密码
- NOIP 2005 过河
- 【ArcGIS|空间分析】地理编码
- 数据结构--酒店管理系统(C语言)
- 字体推荐——sarasa更纱黑体
- 虚拟服务器liter,liter_sheng
- 1024这天,马蜂窝程序员选出的最好语言是…
- 基于Echarts实现可视化数据大屏实时监测地图
- 从阿里云邮箱迁移至网易邮箱
- 车载gps位置服务器,车载GPS监控系统工作原理简介
- 笔记本卡顿不流畅是什么原因_简单解决电脑不流畅经常卡顿问题,非常有用快点看看...
- 国内主流foundry工艺
- 前端 Leader 如何做好团队规划?阿里内部培训总结公开
- 第三章 硬件描述语言verilog(一)
- linux截图工具带编辑器,Screenshot Editor
热门文章
- Coding the Matrix Week 2 The Vector Space作业
- 固件是通用的吗_如何升级AirPods固件?
- 变速更顺滑_CVT变速箱中的小弱鸡?10万公里必坏?变速箱该如何养护?
- python空集合_python空集合
- GMAT英语语法:量词及一些单复数问题详解。附相关错句改正
- 绝地求生2017.7.27服务器维护,绝地求生大逃杀更新内容 7月27日更新了什么
- python十进制转化为二进制_十进制转化为二进制的Python 3.2 代码
- Hadoop高可用集群搭建-1、服务器等基础环境配置
- 利刃 MVVMLight 2:Model、View、ViewModel结构以及全局视图模型注入器的说明
- 开发常用常用插件介绍