精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-18
nianien 写道 静态代码块和静态成员变量加载是有先后顺序的好不好? public class InitDemo { private static Demo d1 = new Demo(1); private static Demo d2 = new Demo(2); private static Demo d3 = new Demo(3); static { d1 = new Demo(0); d1 = new Demo(0); d1 = new Demo(0); } public static void main(String[] args) throws ClassNotFoundException { System.out.println(); } } class Demo { public Demo(int count) { System.out.println(count); } } 从测试结果你可以看到,静态代码块执行顺序要晚于静态字段,因此,我们常用静态代码块改写初始值,字段默认初始值为null,执行静态代码块就是改写null值,它并不是最初的赋值 “静态代码块执行顺序要晚于静态字段” 这句话不准确。静态代码的初始化顺序取决于 声明的顺序,没有绝对的 静态代码块晚于静态字段。 看下面的代码: public class InitDemo { static { d1 = new Demo(4); } private static Demo d1 = new Demo(1); static { d1 = new Demo(5); } private static Demo d2 = new Demo(2); public static void main(String[] args) throws ClassNotFoundException { System.out.println(); } } class Demo { public Demo(int count) { System.out.println(count); } } 其实,本质上来说: private static Demo d1 = new Demo(1); 完全等价于: private static Demo d1 = null; static { d1 = new Demo(1); } 它们只是两种不同的书写方法而已。不止静态变量,实例变量也是一样。 实例变量的初始化可以以3种形式定义,但编译器编译的时候,会把各种形式的初始化语句按出现顺序放到构造函数中。 public class InitDemo { Map buf = new HashMap(); { buf.put("aaa", "bbb"); } String s2; public InitDemo() { s2 = "ddd"; } } 等价于: public class InitDemo { Map buf; String s2; public InitDemo() { buf = new HashMap(); buf.put("aaa", "bbb"); s2 = "ddd"; } } |
|
返回顶楼 | |
发表时间:2011-05-18
sswh 写道 nianien 写道 静态代码块和静态成员变量加载是有先后顺序的好不好? public class InitDemo { private static Demo d1 = new Demo(1); private static Demo d2 = new Demo(2); private static Demo d3 = new Demo(3); static { d1 = new Demo(0); d1 = new Demo(0); d1 = new Demo(0); } public static void main(String[] args) throws ClassNotFoundException { System.out.println(); } } class Demo { public Demo(int count) { System.out.println(count); } } 从测试结果你可以看到,静态代码块执行顺序要晚于静态字段,因此,我们常用静态代码块改写初始值,字段默认初始值为null,执行静态代码块就是改写null值,它并不是最初的赋值 “静态代码块执行顺序要晚于静态字段” 这句话不准确。静态代码的初始化顺序取决于 声明的顺序,没有绝对的 静态代码块晚于静态字段。 看下面的代码: public class InitDemo { static { d1 = new Demo(4); } private static Demo d1 = new Demo(1); static { d1 = new Demo(5); } private static Demo d2 = new Demo(2); public static void main(String[] args) throws ClassNotFoundException { System.out.println(); } } class Demo { public Demo(int count) { System.out.println(count); } } 其实,本质上来说: private static Demo d1 = new Demo(1); 完全等价于: private static Demo d1 = null; static { d1 = new Demo(1); } 它们只是两种不同的书写方法而已。不止静态变量,实例变量也是一样。 实例变量的初始化可以以3种形式定义,但编译器编译的时候,会把各种形式的初始化语句按出现顺序放到构造函数中。 public class InitDemo { Map buf = new HashMap(); { buf.put("aaa", "bbb"); } String s2; public InitDemo() { s2 = "ddd"; } } 等价于: public class InitDemo { Map buf; String s2; public InitDemo() { buf = new HashMap(); buf.put("aaa", "bbb"); s2 = "ddd"; } } 嗯,你说的对,以后得多向你学习了~ |
|
返回顶楼 | |
发表时间:2011-05-18
[quote="sswh]
public static void main(String[] args) throws ClassNotFoundException { Class.forName("my.SingleTon", false, Test.class.getClassLoader()); System.out.println("做点其他事情..."); SingleTon.getInstance(); } } [quote name="kingkan"] 调用静态方法或属性不用实例化。 调用对象方法或属性肯定要实例化。 请问kingkan说法对不对? 我测试了一下,即使调用静态方法,静态代码块和静态字段都会初始化的 |
|
返回顶楼 | |
发表时间:2011-05-18
nianien 写道 [quote="sswh]
public static void main(String[] args) throws ClassNotFoundException { Class.forName("my.SingleTon", false, Test.class.getClassLoader()); System.out.println("做点其他事情..."); SingleTon.getInstance(); } } [quote name="kingkan"] 调用静态方法或属性不用实例化。 调用对象方法或属性肯定要实例化。 请问kingkan说法对不对? 我测试了一下,即使调用静态方法,静态代码块和静态字段都会初始化的 关于Class.forName对一个类实例化时,static关键字修饰的变量初始化与否与类加载器有关, 默认forName0(className, true, ClassLoader.getCallerClassLoader()); 如果为forName0(className, false, ClassLoader.getCallerClassLoader());那么就不会初始化类中的static变量 http://technoboy.iteye.com/blog/1005718 |
|
返回顶楼 | |
发表时间:2011-05-18
在哪看过,最好的单例模式是只含一个元素的enum
|
|
返回顶楼 | |
发表时间:2011-05-18
赵精龙 写道 在哪看过,最好的单例模式是只含一个元素的enum
给出代码来,学习一下~ |
|
返回顶楼 | |
发表时间:2011-05-18
最后修改:2011-05-18
nianien 写道 [quote name="kingkan"] 调用静态方法或属性不用实例化。 调用对象方法或属性肯定要实例化。 请问kingkan说法对不对? 我测试了一下,即使调用静态方法,静态代码块和静态字段都会初始化的 好像kingkan说的意思是 类不用实例化也可以调用类的静态方法。 这个说法没错,但和你说的应该不是一个意思。 你说的“调用静态方法,静态代码块和静态字段都会初始化的”,没错,是这样的。 关于类的初始化,在《深入Java虚拟机》中这样描述: 引用 Java虚拟机在首次主动使用类型时初始化它们。只有6种活动被认为是主动使用: 创建类的新实例, 调用类中声明的静态方法, 操作类或者接口中声明的非常量静态字段, 调用Java API中特定的反射方法, 初始化一个类的子类, 以及指定一个类作为Java虚拟机启动时的初始化类。 大概意思是,基本上对类上静态字段、方法的操作都会导致类的初始化。 但除了一种特殊情况以外: 如果使用的是静态常量(static final),并且常量值是一个编译时常量表达式, 这时候不会导致类被初始化。 |
|
返回顶楼 | |
发表时间:2011-05-18
nianien 写道 littcai 写道 第一种是延迟加载的,优
从多线程的角度考虑,会不会有并发问题呢? SingleTon 类在系统启动后就已经创建好了,不会产生并发问题,你可以去了解下静态类 |
|
返回顶楼 | |
发表时间:2011-05-18
huanglei7211 写道 nianien 写道 littcai 写道 第一种是延迟加载的,优
从多线程的角度考虑,会不会有并发问题呢? SingleTon 类在系统启动后就已经创建好了,不会产生并发问题,你可以去了解下静态类 必须有并发问题。 |
|
返回顶楼 | |
发表时间:2011-05-18
sswh 写道 nianien 写道 [quote name="kingkan"] 调用静态方法或属性不用实例化。 调用对象方法或属性肯定要实例化。 请问kingkan说法对不对? 我测试了一下,即使调用静态方法,静态代码块和静态字段都会初始化的 好像kingkan说的意思是 类不用实例化也可以调用类的静态方法。 这个说法没错,但和你说的应该不是一个意思。 你说的“调用静态方法,静态代码块和静态字段都会初始化的”,没错,是这样的。 关于类的初始化,在《深入Java虚拟机》中这样描述: 引用 Java虚拟机在首次主动使用类型时初始化它们。只有6种活动被认为是主动使用: 创建类的新实例, 调用类中声明的静态方法, 操作类或者接口中声明的非常量静态字段, 调用Java API中特定的反射方法, 初始化一个类的子类, 以及指定一个类作为Java虚拟机启动时的初始化类。 大概意思是,基本上对类上静态字段、方法的操作都会导致类的初始化。 但除了一种特殊情况以外: 如果使用的是静态常量(static final),并且常量值是一个编译时常量表达式, 这时候不会导致类被初始化。 再次向你致敬,你Java水平比我高,学习了~ |
|
返回顶楼 | |