我们都知道,static 块在初始化的时候,首先执行 static 块区域,然后执行相应的构造方法
package C01;
import java.util.List;
import java.util.ArrayList;
public class TestStatic {
private static List list ;
//静态初始化区
static {
list = new ArrayList();
list.add("测试1");
list.add("测试2");
}
public TestStatic(){
init();
}
public void print(){
for(int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
}
private void init(){
if(null==list){
list = new ArrayList();
}
list.add("测试0");
}
public static void main(String args[]){
TestStatic ts = new TestStatic();
ts.print();
}
}
上面的代码输出为
测试1
测试2
测试0
这个认为是正常的,但是,问题出在下面,当我把这个类改写成单例的时候。
package C01;
import java.util.List;
import java.util.ArrayList;
public class TestStatic {
private static final TestStatic instance = new TestStatic();
private static List list ;
//静态初始化区
static {
list = new ArrayList();
list.add("测试1");
list.add("测试2");
}
private TestStatic(){
init();
}
public void print(){
for(int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
}
private void init(){
if(null==list){
list = new ArrayList();
}
list.add("测试0");
}
public static TestStatic getInstance(){
return instance;
}
public static void main(String args[]){
TestStatic.getInstance().print();
// TestStatic ts = new TestStatic();
// ts.print();
}
}
这次输出的是
测试1
测试2
重结果上来看list.add("测试0");好像没有执行。
后来经过打注视调试,发现了问题的所在。
是static块在作怪
修改一下代码
package C01;
import java.util.List;
import java.util.ArrayList;
public class TestStatic {
private static final TestStatic instance = new TestStatic();
private static List list ;
//静态初始化区
static {
list = new ArrayList();
list.add("测试1");
list.add("测试2");
System.out.println("static block is called !");
}
public TestStatic(){
init();
System.out.println("TestStatic is called !");
}
public void print(){
for(int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
}
private void init(){
if(null==list){
list = new ArrayList();
}
list.add("测试0");
System.out.println("init is called !");
}
public static TestStatic getInstance(){
return instance;
}
public static void main(String args[]){
TestStatic.getInstance().print();
// TestStatic ts = new TestStatic();
// ts.print();
}
}
这次输出的是:
init is called !
TestStatic is called !
static block is called !
测试1
测试2
问题出现在第三行”static block is called !“
static 块并没有 在构造方法前执行
static 块执行的时候覆盖掉了已经初始化的list,重新创建了一个实例。
getInstance 方法 强迫了 instance 初始化,构造方法,抢先了static块。
分享到:
相关推荐
本主题将深入探讨Linux环境下Java编程中的变量、关键字以及MyEclipse集成开发环境的快捷键,同时也会涉及到Java方法的使用。 首先,让我们来谈谈“Linux中Java变量与java关键字”。在Java编程中,变量是存储数据的...
Java数据库驱动,通常被称为JDBC(Java Database Connectivity)驱动,是Java编程语言中连接到数据库的关键组件。在Java中,JDBC驱动程序提供了一个标准的API,使得开发人员能够使用SQL语句与各种数据库进行交互。这...
在Java编程语言中,`try-catch-finally`语句块是异常处理的关键构造,它允许程序员优雅地处理可能出现的异常情况。`return`语句则用于从方法中返回一个值或者结束方法的执行。当这两者结合在一起时,就会出现一些...
`volatile`在DCL(Double Check Locking)模式中的应用也是典型的场景。DCL是一种延迟初始化单例的策略,其核心在于确保单例的唯一性以及初始化过程的线程安全。以下是一个DCL模式的简化示例: ```java public ...
在Java编程语言中,处理图像是一项常见的任务,其中包括图片压缩。Java提供了丰富的API来处理图像,其中`java.awt.image.BufferedImage`和`javax.imageio.ImageIO`类是核心工具。本篇文章将深入探讨如何利用Java后台...
Java中的`this`关键字是一个非常重要的概念,它用于在代码中引用当前对象的实例变量、方法或者构造器。本文将详细探讨`this`的三种主要使用方法。 1. **引用当前对象的变量或方法** 当类的成员变量与局部变量(如...
此外,HashMap和Hashtable也是Java面试中的重要知识点。HashMap类没有分类或者排序。它允许一个null键和多个null值。Hashtable类似于HashMap,但是不允许null键和null值。它也比HashMap慢,因为它是同步的。 在Java...
在Java编程中,获取计算机的硬件信息,如CPU使用率和内存使用情况,是一项常见的需求。这主要应用于系统监控、性能分析以及资源管理等方面。Java虽然不像C++或C#那样可以直接调用操作系统API,但它提供了Java ...
Java中的线程分为两种类型:守护线程(Daemon)和用户线程(User)。这两类线程的主要区别在于它们对Java虚拟机(JVM)生命周期的影响。守护线程主要是为其他线程提供服务,比如垃圾回收线程,而用户线程则包含应用...
在Java编程语言中,`JFrame`是Swing库中的一个关键组件,它代表了窗口应用程序的基本框架。`JFrame`是所有Swing GUI应用程序的基础,因为它提供了展示其他组件(如按钮、文本框等)的区域。让我们深入探讨一下如何在...
首先,我们来谈谈如何使用Java制作基本的菜单选择。在Java中,我们可以利用控制台输入(Console Input)和条件语句(如if-else或switch-case)来实现一个简单的命令行菜单。菜单通常包括一系列选项,用户通过输入...
java中的map遍历有多种方法,从早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下具体的用法以及各自的优缺点。 先初始化一个map public class TestMap { public static Map<Integer>...
在实际的Java开发项目中,自定义异常是提高代码可读性和可维护性的重要手段。异常处理是程序设计的关键部分,它有助于捕获并处理在程序执行过程中可能出现的错误或异常情况。Java提供了丰富的异常处理机制,包括预...
在DCL模式中,`volatile`关键字的第一次检查可以避免不必要的同步,而第二次检查加上`synchronized`块确保了线程安全。然而,如前所述,由于JMM的复杂性,还需要理解CPU指令重排序和缓存一致性协议(如MESI协议)的...
接下来,我们谈谈Java开发的经验技巧。在Java游戏开发中,性能优化是关键。确保使用高效的数据结构和算法,比如使用ArrayList而非LinkedList进行频繁的插入和删除操作,因为ArrayList的随机访问速度更快。此外,避免...
42、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 12 43、说出一些常用的类,包,接口,请各举5 个。 12 44、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类?是否可以...
在一个`try-catch-finally`结构中,即使`try`块抛出了异常并被`catch`捕获处理,`finally`块中的代码也会被执行。这通常用于资源的释放,如关闭文件流等,确保无论是否发生异常,某些必要的清理工作都会被执行。 -...
4. **谈谈Java的垃圾回收机制。** Java自动管理内存,通过垃圾回收器回收不再使用的对象所占用的内存。它检测并释放无引用的对象,防止内存泄漏。 5. **什么是异常处理?** 异常处理是Java中的错误处理机制,通过...
- **final**:这是Java中的一个关键字,用于定义不可变的变量或方法。当一个变量被声明为final时,其值在初始化后就不能再被改变。如果是一个对象引用,则该引用不能指向另一个对象。对于方法来说,如果它被声明为...
在Java编程语言中,`final`关键字、抽象类和接口是面向对象编程的重要概念。它们各自扮演着不同的角色,帮助我们构建更健壮、可维护的代码结构。 首先,`final`关键字在Java中具有多种用途。它可以用来修饰类、方法...