`
zhangdp_neu
  • 浏览: 10669 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

也谈谈Java中的static块

阅读更多
我们都知道,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块。
1
0
分享到:
评论
4 楼 highphd 2015-07-02  
static { list = new ArrayList();
list.add("测试1");
list.add("测试2");
}

private static final TestStatic instance = new TestStatic();

如果把这个new放到static后面,则可以输出0

测试1
测试2
测试0
3 楼 mischief 2011-10-11  
 
2 楼 TedYin 2011-09-28  
TedYin 写道
  public static void main(String args[]){  
43.        TestStatic.getInstance().print();  
44.//      TestStatic ts = new TestStatic();  
45.//      ts.prisnt();  
46.    }  

上面代码中第43行实用的是静态方法,并没有创建对像,所以就没有调用init()方法,与static区块半毛钱关系都没有。

本人失误,看错了。楼主见谅!
1 楼 TedYin 2011-09-28  
  public static void main(String args[]){  
43.        TestStatic.getInstance().print();  
44.//      TestStatic ts = new TestStatic();  
45.//      ts.prisnt();  
46.    }  

上面代码中第43行实用的是静态方法,并没有创建对像,所以就没有调用init()方法,与static区块半毛钱关系都没有。

相关推荐

    Linux中Java变量与java关键字。MyEclipse快捷键大全。Java方法

    本主题将深入探讨Linux环境下Java编程中的变量、关键字以及MyEclipse集成开发环境的快捷键,同时也会涉及到Java方法的使用。 首先,让我们来谈谈“Linux中Java变量与java关键字”。在Java编程中,变量是存储数据的...

    java数据库驱动jar包

    Java数据库驱动,通常被称为JDBC(Java Database Connectivity)驱动,是Java编程语言中连接到数据库的关键组件。在Java中,JDBC驱动程序提供了一个标准的API,使得开发人员能够使用SQL语句与各种数据库进行交互。这...

    谈谈Java中try-catch-finally中的return语句

    在Java编程语言中,`try-catch-finally`语句块是异常处理的关键构造,它允许程序员优雅地处理可能出现的异常情况。`return`语句则用于从方法中返回一个值或者结束方法的执行。当这两者结合在一起时,就会出现一些...

    谈谈Java中Volatile关键字的理解

    `volatile`在DCL(Double Check Locking)模式中的应用也是典型的场景。DCL是一种延迟初始化单例的策略,其核心在于确保单例的唯一性以及初始化过程的线程安全。以下是一个DCL模式的简化示例: ```java public ...

    Java 图片压缩

    在Java编程语言中,处理图像是一项常见的任务,其中包括图片压缩。Java提供了丰富的API来处理图像,其中`java.awt.image.BufferedImage`和`javax.imageio.ImageIO`类是核心工具。本篇文章将深入探讨如何利用Java后台...

    谈谈 Java 中 this 的使用方法

    Java中的`this`关键字是一个非常重要的概念,它用于在代码中引用当前对象的实例变量、方法或者构造器。本文将详细探讨`this`的三种主要使用方法。 1. **引用当前对象的变量或方法** 当类的成员变量与局部变量(如...

    Java面试题,他会给你很好的Java面试准备,第一,谈谈final, finally, finalize的区别,第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

    此外,HashMap和Hashtable也是Java面试中的重要知识点。HashMap类没有分类或者排序。它允许一个null键和多个null值。Hashtable类似于HashMap,但是不允许null键和null值。它也比HashMap慢,因为它是同步的。 在Java...

    Java获取计算机CPU、内存等信息

    在Java编程中,获取计算机的硬件信息,如CPU使用率和内存使用情况,是一项常见的需求。这主要应用于系统监控、性能分析以及资源管理等方面。Java虽然不像C++或C#那样可以直接调用操作系统API,但它提供了Java ...

    谈谈Java中的守护线程与普通线程

    Java中的线程分为两种类型:守护线程(Daemon)和用户线程(User)。这两类线程的主要区别在于它们对Java虚拟机(JVM)生命周期的影响。守护线程主要是为其他线程提供服务,比如垃圾回收线程,而用户线程则包含应用...

    java中jfame的使用代码JMenubar.Jmenu.JmenuItem

    在Java编程语言中,`JFrame`是Swing库中的一个关键组件,它代表了窗口应用程序的基本框架。`JFrame`是所有Swing GUI应用程序的基础,因为它提供了展示其他组件(如按钮、文本框等)的区域。让我们深入探讨一下如何在...

    Java制作菜单+时钟

    首先,我们来谈谈如何使用Java制作基本的菜单选择。在Java中,我们可以利用控制台输入(Console Input)和条件语句(如if-else或switch-case)来实现一个简单的命令行菜单。菜单通常包括一系列选项,用户通过输入...

    谈谈Java中遍历Map的几种方法

    java中的map遍历有多种方法,从早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下具体的用法以及各自的优缺点。  先初始化一个map public class TestMap {  public static Map&lt;Integer&gt;...

    实际项目中java自定义异常

    在实际的Java开发项目中,自定义异常是提高代码可读性和可维护性的重要手段。异常处理是程序设计的关键部分,它有助于捕获并处理在程序执行过程中可能出现的错误或异常情况。Java提供了丰富的异常处理机制,包括预...

    通过实例程序验证与优化谈谈网上很多对于Java DCL的一些误解以及为何要理解Java内存模型.doc

    在DCL模式中,`volatile`关键字的第一次检查可以避免不必要的同步,而第二次检查加上`synchronized`块确保了线程安全。然而,如前所述,由于JMM的复杂性,还需要理解CPU指令重排序和缓存一致性协议(如MESI协议)的...

    Java游戏手柄与我Java开发Java经验技巧共4页.p

    接下来,我们谈谈Java开发的经验技巧。在Java游戏开发中,性能优化是关键。确保使用高效的数据结构和算法,比如使用ArrayList而非LinkedList进行频繁的插入和删除操作,因为ArrayList的随机访问速度更快。此外,避免...

    java面试宝典

    42、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 12 43、说出一些常用的类,包,接口,请各举5 个。 12 44、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类?是否可以...

    变态JAVA面试32问及答案

    在一个`try-catch-finally`结构中,即使`try`块抛出了异常并被`catch`捕获处理,`finally`块中的代码也会被执行。这通常用于资源的释放,如关闭文件流等,确保无论是否发生异常,某些必要的清理工作都会被执行。 -...

    java面试题

    4. **谈谈Java的垃圾回收机制。** Java自动管理内存,通过垃圾回收器回收不再使用的对象所占用的内存。它检测并释放无引用的对象,防止内存泄漏。 5. **什么是异常处理?** 异常处理是Java中的错误处理机制,通过...

    JAVA程序员面试32问

    - **final**:这是Java中的一个关键字,用于定义不可变的变量或方法。当一个变量被声明为final时,其值在初始化后就不能再被改变。如果是一个对象引用,则该引用不能指向另一个对象。对于方法来说,如果它被声明为...

    Java学习笔记---15.面向对象编程10-Java中final关键字,抽象类与接口

    在Java编程语言中,`final`关键字、抽象类和接口是面向对象编程的重要概念。它们各自扮演着不同的角色,帮助我们构建更健壮、可维护的代码结构。 首先,`final`关键字在Java中具有多种用途。它可以用来修饰类、方法...

Global site tag (gtag.js) - Google Analytics