`
shifulong
  • 浏览: 59261 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java静态块的一个小坑

    博客分类:
  • java
 
阅读更多
public class Student {

	private static List<Student> studentList = new ArrayList<Student>();

	static {
		studentList.add(new Student(Student.S_NAME, Student.NAME, Student.AGE));
		studentList.add(new Student(Student.S_NAME, Student.NAME, Student.AGE));
	}

	private final static String S_NAME = "aaa"; // String pool.
	private final static String NAME = new String("bbb");
	private final static Integer AGE = 11;

	private String sname;
	private String name;
	private Integer age;

	public Student(String sname, String name, Integer age) {
		this.sname = sname;
		this.name = name;
		this.age = age;
	}

	public static void main(String[] args) {
		System.out.println(studentList);
	}

	@Override
	public String toString() {
		return "Student [sname=" + sname + ", name=" + name + ", age=" + age
				+ "]";
	}
}

下面是输出:
[Student [sname=aaa, name=null, age=null], Student [sname=aaa, name=null, age=null]]

按照以前的理解,不应该是这个结果的。

于是乎问了下大神,得出了以下结论:

1,静态变量声明和初始化是两个过程;

2, String字面常量有个pool, 每次有新的常量出现的时候, 先把它放入pool, 然后直接把变量引用指向pool中的位置;

3. java中的字面常量在编译的时候被替换成真实的值,具体表现为字符串常量和基本类型常量。

4.static 块java language specification是保证happen before的,也就是有顺序的。

所以代码等同于:

	private static List<Student> studentList = null;
	
	private final static String S_NAME = "aaa"; // String pool.
	private final static String NAME = null;
	private final static Integer AGE = null;
	static {
		studentList = new ArrayList<Student>();
		studentList.add(new Student(Student.S_NAME, Student.NAME, Student.AGE));
		studentList.add(new Student(Student.S_NAME, Student.NAME, Student.AGE));
		NAME = new String("bbb");
		AGE = 11;
	 }


所以输出结果可定不对啊!!!
改成下面这样就可以了,其实就是换一下声明顺序。
	private static List<Student> studentList = new ArrayList<Student>();
	
	private final static String S_NAME = "aaa"; // String pool.
	private final static String NAME = new String("bbb");
	private final static Integer AGE = 11;
	
	static {
		studentList.add(new Student(Student.S_NAME, Student.NAME, Student.AGE));
		studentList.add(new Student(Student.S_NAME, Student.NAME, Student.AGE));
	}


输出结果
[Student [sname=aaa, name=bbb, age=11], Student [sname=aaa, name=bbb, age=11]]


自身引用自身的静态变量时才会发生上面个的情况(Student引用Student的static),
如果Student引用Teacher的静态常量就不会有上面这个问题,因为Teacher已经初始化完成所有的静态常量了。
分享到:
评论

相关推荐

    Java避坑指南:Java高手笔记代码篇.rar

    在Java编程语言的世界里,程序员们常常面临各种各样的陷阱和难题。...这份“Java避坑指南:Java高手笔记代码篇”应该包含了这些领域的实战经验和示例代码,为读者提供了一条避开陷阱、提升技能的道路。

    Java中增强for循环的实现原理和坑详解

    在增强for循环中,Java编译器会将其转换为一个普通的for循环,使用迭代器来遍历集合或数组。迭代器会在遍历过程中维护一个索引,指向当前要遍历的元素。这样,增强for循环可以简洁地遍历集合或数组,提高编程效率。 ...

    C++造的坑Java来补,补坑的路上Java接口怎么写.pdf

    标题所指的知识点,即“C++造的坑Java来补,补坑的路上Java接口怎么写”,说明了Java接口的设计初衷之一是为了弥补C++语言中多继承带来的问题。C++支持多重继承,即一个类可以继承自多个父类,这带来了诸如菱形继承...

    Java 面试中的陷阱

    从给定的文件标题“Java面试中的陷阱”和描述“Java面试中一些常用问题的小总结”,我们可以提炼出一系列重要的Java知识点,这些知识点是面试官在评估候选人时常常关注的领域。下面将对这些知识点进行详细解析,以...

    详解Java 集合类 List 的那些坑

    第一个坑:Arrays.asList 方法返回的 List 不支持增加、删除操作 Arrays.asList 方法返回的 List 并不是我们常用的 java.util.ArrayList,而是 Arrays 的静态内部类 java.util.Arrays.ArrayList,该类继承自抽象类 ...

    ElasticSearch Java API 中文文档

    标签《ES Java API 中文文档》强调了文档的内容属性,它属于ElasticSearch的一个重要组成部分,即用Java语言进行数据交互和操作的应用程序接口部分。 从部分内容中可以提取出以下知识点: 1. **Transport Client**...

    java经典游戏和经典实例含源码(必须得收藏了亲)

    这个5分当然是物有所值,我不会坑你们的亲,是女友当初想学java帮她收集的...还有运行于JBuilder的100个java实例,可以说应有尽有了,希望大家java水平更上一层楼,第一次解压无需密码,里面有一个后面文件要的密码说明

    免费Java Excel类库_Free Spire.XLS for Java_2.2.0.zip

    Free Spire.XLS for Java 是用于操作处理Excel文档的Java组件。开发人员使用它可以在 Java 应用程序中实现创建、操作、转换和打印 Excel 工作表,并且运行环境无需安装 Microsoft Office 或 Microsoft Excel。该类库...

    浅谈java 重写equals方法的种种坑

    在下面的示例代码中,我们将看到一个不区分大小写的字符串类的定义。这是一个反例,违反了对称性。 ```java public class CaseInsensitiveString { private final String s; public CaseInsensitiveString...

    微信小程序微信小程序开发的投票评选系统(java)(包括源码,数据库,教程).zip

    小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程...

    Java中常见的坑

    例如,当你声明`String s = "Hello"`时,`s`并不是一个对象,而是指向一个字符串对象的引用。这意味着,字符串是不可变的,因此当你执行`s += "!"`时,实际上是创建了一个新的字符串对象,而`s`的引用被更新为新对象...

    java基础知识源码

    最基础的java知识,适用于小白,和初入java坑的小白。

    一份超级详细的Java面试题【大厂面试真题+Java学习指南+工作总结】

    Java日常开发的21个坑,你踩过几个? CAS乐观锁解决并发问题的一次实践 写代码有这些想法,同事才不会认为你是复制粘贴程序员 程序员必备:Java日期处理的十个坑 内存泄漏问题的分析和解决方案 程序员必备基础:加签...

    java技术书籍合集

    编写高质量代码:改善Java程序的151个建议, Spring 技术内幕 机器学习实践指南:案例应用解析(第2版) Java并发编程的艺术 , Java TCP_IP Socket编程(2版), 深入理解Java虚拟机(第2版), 机器学习实践指南:...

    Java项目-基于微信小程序的微信阅读小程序(包括源码,数据库,教程).zip

    Java 毕业设计,小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目...

    Java项目-基于微信小程序的微信小程序租房平台(包括源码,数据库,教程).zip

    Java 毕业设计,小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目...

    Java项目-基于微信小程序的美容院管理系统(包括源码,数据库,教程).zip

    Java毕设,小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为...

    JAVA高并发.xmind

    JAVA高并发.xmind

    兼容C# VB.net的TripleDES加解密的java源码

    若指定参数为unicode,则转换后前二字节为-2,-1,后两字节为一个字符(高位在前,低位在后);而DotNET转换后,无前二字节,低位在前,高位在后。因此,为与DotNET一致,Java用unicode参数取得字节数组后须再次处理...

    java concurrent source code

    比如对大数据、分布式、高并发类的专题进行攻克时,立即遇到针对java.lang包中线程类的学习,但线程类的学习并不像JDBC一样简单,学习曲线陡峭,多弯路与“坑”。要学习这些热点技术,Java多线程技术避无可避。而...

Global site tag (gtag.js) - Google Analytics