class Singleton {
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
}
// 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
}
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
}
// 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
}
obj.counter1==1
obj.counter2==0
大家讨论,说对了理由给分.
http://community.csdn.net/Expert/topic/4275/4275850.xml?temp=.1619379
class Singleton {
private static Singleton obj = new Singleton();
public static String s = obj.print();
public static int counter1;
public static int counter2=0;
private Singleton() {
counter1++;
counter2++;
}
public String print(){
return counter1+" "+counter2;
}public static Singleton getInstance(){
return obj;
}
}
// 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
System.out.println(obj.s);
}
}
//对Java还不是很了解,不知道有没有规定static成员的
//初始化关系,如果没有,那就变成编辑器有关了.
//不过从程序可推测static的声明和初始化是分两遍来
//完成的.
//调整一下次序,就能更好的表达语义了.
---初学者class Singleton { public static int counter1;
public static int counter2 = 0; private static Singleton obj = new Singleton();
private Singleton() {
counter1++;
counter2++;
System.out.println("counter1= " + counter1);
System.out.println("counter2= " + counter2);
} public static Singleton getInstance() {
return obj;
}
}public class Single {
public static void main(String[] args) {
System.out.println("obj.counter1==" + Singleton.counter1);
System.out.println("obj.counter2==" + Singleton.counter2);
}
}
执行结果是:
counter1= 1
counter2= 1
obj.counter1==1
obj.counter2==1你上面的这个程序说明了类初始化的时候的关系,就是
Singleton.counter1的时候是先调用构造函数的.
调用构造函数的时候,是先执行
counter1++和2++,
这个时候还没有执行
public static int counter1;
public static int counter2 = 0;
只是看在static的面子上给他在内存里面分配了一个地址并且初始化为0.
而调用
System.out.println("obj.counter1==" + Singleton.counter1);
System.out.println("obj.counter2==" + Singleton.counter2);
的时候,还是没有执行赋值,这样后面的两个也是1了!
呵呵 interhanchi(闭关修练中!) 兄
你的例子很不错,也很经典,问题一目了然.
佩服,俺学习的榜样哈!keiy() 兄,你的帖子看过了 呵呵 感觉问题没有弄的太清楚了就结贴了哈 呵呵还有啊 无名兄,前面有个兄弟点名让你回帖呢 估计你没有看到.
哪个兄弟给个好点的java的群啊???
的例子的确很不错,学习!
如果
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
的顺序改为:obj的的申明放在counter2的申明之后结果就是counter1=1,counter2=1;
obj.counter1==1
obj.counter2==1
准确的说是
Singleton.counter1==1
Singleton.counter2==1初始化的值是用被覆盖的.我是这样理解的.
不过最好不要写这样的代码.---初学者
Singleton.counter1==1
Singleton.counter2==1
counter1和counter2是静态成员.会比类优先这初始化.而这时,他们两个分别就有了一个初始化值了,即0;接着就是类的构造方法的执行.即:private static Singleton obj = new Singleton();
所以,两个值分别增1.就得到了
Singleton.counter1==1
Singleton.counter2==1总的来说:这个题无非就是一个静态数据初始化与类的初始化问题.
初始化了一次,static初始化的时候,只是分配在内存里面的地址,然后分一个默认值0,
赋值的事情,是在后来++后.
wlmmlw(吴铭)
我的意思,只是想咱讨论讨论代码初始化和执行的顺序 呵呵
上述说法引自java编程思想第三版
public class Test1
{
public static void main(String[] args)
{
Myclass myclass = Myclass.CreateMyclass();
System.out.println(myclass.counter1);
System.out.println(myclass.counter2);
}
}class Myclass
{
private static final Myclass obj = new Myclass();
public static int counter1;
public static int counter2=3; private Myclass()
{
counter1++;
counter2++;
System.out.println("Myclass () 里的 counter1 = "+counter1);
System.out.println("Myclass () 里的 counter2 = "+counter2);
}
public static Myclass CreateMyclass()
{
return obj;
}
}可见执行private static final Myclass obj = new Myclass();前,语句 public static int counter1; public static int counter2=3;还没有被执行。这时系统就当counter = 0;counter=0看待。 执行完构造涵数后再执行后两条语句,这时因为counter1没有明确的值,所以把构造函数的结果给了它。 因为counter2有确定的值3, 所以把3赋给了它。不知我说得对不, 请楼主说明。继续关注。
上述说法引自java编程思想第三版
我不这样认为,我觉得还是有static修饰的int变量如果在构造函数里面应用的时候,值绝对是0
昨天上课的时候我还专门问了我们老师的,她也是这么说的,而且程序的执行结果也表明是这样.
呵呵 把你应用哪儿的话贴上来看看吧.
lgh2008(ar_guang)可见执行private static final Myclass obj = new Myclass();前,语句 public static int counter1; public static int counter2=3;还没有被执行。
呵呵 ,基本上就是这个意思.
执行构造函数的时候,用到了变量,而变量在构造函数下面,所以只能用默认的int变量的值.
这里注意,static类型的变量是在类被加载的时候先分配内存的,也就是没有执行构造函数的时候就先搜索static关键字的变量,然后分配内存.
所以说,你说没有执行是不全对的 呵呵
private static Singleton obj = new Singleton();
public int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
}
// 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
}
//只是初始化次序问题
class Singleton {
private static Singleton obj; //其实在JDK编译的时候都是先将属性定义出来。写在方法外的int类型默认为 "0"
public static int counter1;
public static int counter2;
static{ //静态变量是在静态块中初始化的,先实例obj,调用构造函数两个数字都为"1";现在要调用counter2负值(因为counter1没有附值还等于"1")
obj = new Singleton();
counter2=0;
} private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
}
如果将private static Singleton obj = new Singleton(); 往后写两行,这个程序就没有任何悬念了。 即。
class Singleton {
public static int counter1;
public static int counter2 = 0;
private static Singleton obj = new Singleton();
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
}
// 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
}
上述说法引自java编程思想第三版可见执行private static final Myclass obj = new Myclass();前,语句 public static int counter1; public static int counter2=3;还没有被执行。是真是假,就设public static int counter2=5,看看结果就一目了然。
class Singleton {
public static Singleton obj = new Singleton();
public static int counter1;
public static int counter2=0;
private Singleton() {
counter1++;
counter2++;
}
}
// 程序2
public class MyMain {
public static void main(String[] args) {
System.out.println("obj.counter1=="+Singleton.obj.counter1);
System.out.println("obj.counter2=="+Singleton.obj.counter2);
}
}
相信对于这一题,这样简化不会有什么影响吧。
小弟认为:由于静态变量是在程序运行前初始化的,如果存在多个静态成员,必然有个顺序问题,如果各个静态成员互不相干还好,如果有了牵连(本例中obj初始化的时候对counter2进行了操作!),本来大家平起平坐的,你凭什么干涉我(counter2很不满,我还没初始化呢!)。于是,counter2在obj初始化后依然毅然重新初始化了自己(public static counter2=0)。
嘿嘿,小弟愚见,望楼主赏点分花花!
呵呵,有没有static执行的机理可是大不一样哈强烈建议大家看看 jiaxiang131(小白) 兄发的第二贴,
此贴经典之极,世所罕见!俺强烈怀疑你是不是反编译class出来的 要不怎么对运行的 内在顺序了如的这么指掌?
恩,再次推荐一下.lgh2008(ar_guang)兄,
呵呵,你明白我的意思,我也明白你指的是啥,哈,这才叫交流嘛,不必拘泥与语言形式上的偏差误会
呵呵,听说神交是交流的最高形式哈,估计就是这样吧 呵呵luyisir2(小小程序员) 兄,
花花会有的,没有想到我的一个帖子居然这么多兄弟关注,呵呵,给分的一定不会手软
里面的几个问题弄清楚了这个问题算玩玩全全彻底搞清楚了
//powered by kestrel@byhh,MyMain.javaclass Singleton {
private static Singleton obj = new Singleton();
public static String s=obj.print();
//public static String s =new String(counter1+" "+counter2);
//为什么这里这样写会产生不能引用没有定义变量的错误?郁闷!public static int counter1;
public static int counter2=0;
public static String t=new String(counter1+" "+counter2);private Singleton() {
counter1++;
counter2++;
System.out.println("counter1="+counter1);
System.out.println("counter2="+counter2);
}
public String print(){
return counter1+" "+counter2;
}public static Singleton getInstance(){
return obj;
}
}
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
//这里obj是新生成的一个另外分配了内存的对象吗?还是初始化Singleton而产生的一个静态的对象?
//期待高人指点ing...
System.out.println("s="+ obj.s);
System.out.println("t="+ obj.t);
//为什么这里会输出1,0??
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
System.out.println(obj.s);
}
}
counter2=1
s=1 1
t=1 0
obj.counter1==1
obj.counter2==0
1 1呵呵 大家如果看明白了上面的帖子,基本上差不多了
很高兴和你一起讨论这个程序,它确实很有挑战性,我整整调试了一个上午,当我明白它的那一刻,心里有说不出的高兴。谢谢你为大家提供这样的乐趣。在这里我就不向你要分了(虽然我现在的分还很少),但你要答应我一个条件,把我加为好友,QQ:15271295。 这一点不过份吧。
对应楼主代码:
程序首先初始化static Singleton obj静态变量,此时分配空间给obj后obj的存储空间初始化为2进制0,也就是说此时counter1,counter2的值都是0。执行构造函数后都变为1。
接着初始化static counter1但是没有初始化语句,所以counter1仍然是1。
同理counter2由于执行初始化语句就成为0了。
楼主问题很有启发性,学到不少东西
最后行代码:
System.out.println(obj.s); //结果是1 1是不是因为静态字符串s在
public static String s=obj.print();初始化了,字符串是不变的.所以才输出1 1开始以为是1 0
它在赋值的时候,counter1和counter2还没有执行赋值语句,也就是如果把这句放到
public static int counter1=0;
public static int counter2;
后面结果就不一样了 呵呵
程序文件在编译时扫描类的所有成员变量字段,包括静态的,并以0值来初始化(对象的引用初始化为null),并分配内存
而类加载时,将会严格按照声明顺序进行初始化。
不知道是不是这个意思呢?
obj.counter1==1obj.counter2==0不是
obj.counter1==1obj.counter2==1
为什么?这些是不是要涉及JDK底层