A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© loading……99.9 中级黑马   /  2013-10-16 19:06  /  2050 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 loading……99.9 于 2013-10-17 11:15 编辑

今天看见个题,不知为什么?求大神解答。
  1. public class Test
  2. {
  3.         private static Test test = new Test();
  4.         private static int  j ;
  5.         private static int i = 0;
  6.         
  7.         private Test()
  8.         {
  9.                 j ++;
  10.                 i ++;
  11.         }
  12.         
  13.         public static Test getInstance()
  14.         {
  15.                 return test;
  16.         }
  17.         
  18.         public static void main(String[] args)
  19.         {
  20.                 Test.getInstance();
  21.                 System.out.println("j = " + Test.j);
  22.                 System.out.println("i = " + Test.i);
  23.         }
  24. }
复制代码
我感觉都应该输出1,为什么不是的呢?

评分

参与人数 1技术分 +1 收起 理由
李江 + 1

查看全部评分

12 个回复

正序浏览
赖波 中级黑马 2013-10-16 21:43:36
13#
其实我也试了好多种,我觉得有些东西,有明确的规定就没有必要深究,
类的静态成员,是类对象共享的,我们只看结果,不会你创建个对象++了,又创建个对象又++了,那i,j将会变成多少,
你非要说构造方中,ij就是变了,输入出++的值,那将又引出什么还原机制,内存数据转换,数据传递,等问题当然是我瞎说的,而你只记住,类的静态成员,是类对象共享的,创对象不改变静态成员,就不用想了。
其实我也写了代码试过
  1. package day5StaticImportExportBox;

  2. public class StaticXX {
  3.         private static StaticXX test = new StaticXX();
  4.         private static int j;
  5.         private static int i = 1;
  6.         static {
  7.                 j++;
  8.                 i++;
  9.                 System.out.println("静态块中的j:"+j);
  10.                 System.out.println("静态块中的i:"+i);
  11.         }

  12.         private StaticXX() {
  13.                 j++;
  14.                 i++;
  15.                 System.out.println("构造方法中的j:"+j);
  16.                 System.out.println("构造方法中的i:"+i);
  17.         }

  18.         public static StaticXX getInstance() {
  19.                 return test;
  20.         }

  21.         public static void main(String[] args) {
  22.                 StaticXX.getInstance();
  23.                 System.out.println("对象中的j = " + StaticXX.j);
  24.                 System.out.println("对象中的i = " + StaticXX.i);
  25.         }
  26. }
复制代码
回复 使用道具 举报
赖波 发表于 2013-10-16 21:07
上面我说的不对,不全。可能下面理解的思想也有问题,一起讨论,一起学习。
仔细看,有构造函数,有static ...

“也就是说构造方法不改变静态成员”,你这话我也证明了,当我在构造函数里面改成这样时,
  1. private Test()
  2.         {
  3.                 j ++;
  4.                 i ++;
  5.                 System.out.println("j = " + Test.j);
  6.                 System.out.println("i = " + Test.i);
  7.         }
复制代码
结果在这里的输出语句显示i=1,j=1。:dizzy:
回复 使用道具 举报
赖波 中级黑马 2013-10-16 21:07:40
11#
本帖最后由 赖波 于 2013-10-16 21:09 编辑

上面我说的不对,不全。可能下面理解的思想也有问题,一起讨论,一起学习。
仔细看,有构造函数,有static变量,

静态变量只在类第一次使用时加载时进行初始化,在方法区中存在。
第一次用就要初始化,后面根据需要是可以再次赋值,这没有问题。
j第一次用是在构造方法中(j++)为初始化为1,j为1的原因。
可能你会说i 也++了,不急看下面的:

一个类的静态成员,是类对象共享的,意思是不因创建了几个对象后会改变,构造方法就是来创建对象的,也就是说构造方法不改变静态成员,这就是我觉i不变的原因。
回复 使用道具 举报
赖波 发表于 2013-10-16 19:51
静态变量在声明后只能初始化一次

不对吧!
  1. public class Test2
  2. {
  3.         public static int k = 0;
  4.         static
  5.         {
  6.                 k = 1;
  7.                 System.out.println("static1_k = " + Test2.k);
  8.         }
  9.         static
  10.         {
  11.                 k = 2;
  12.                 System.out.println("static2_k = " + Test2.k);
  13.         }
  14.         static
  15.         {
  16.                 k =3;
  17.                 System.out.println("static3_k = " + Test2.k);
  18.         }
  19.        
  20.         public static void main(String[] args)
  21.         {
  22.                 System.out.println("main_k = " + Test2.k);
  23.         }
  24. }
复制代码
这算不算是初始化?
最后输出
static1_k = 1
static2_k = 2
static3_k = 3
main_k = 3
回复 使用道具 举报
赖波 中级黑马 2013-10-16 19:51:29
9#
静态变量在声明后只能初始化一次
回复 使用道具 举报
麦者 发表于 2013-10-16 19:40
郁闷,刚才0写成1了

照你这么说你把0写成了1,那么我又测试了下,
  1. private static int  j ;
  2.         private static int i = 0;
  3.         private static Test test = new Test();
复制代码
只改了下顺序,别的地方没动,这时就是我预期输出的结果,i=1,j=1,前后的不同,差别在哪里呢?
回复 使用道具 举报
麦者 中级黑马 2013-10-16 19:40:17
7#
loading……99.9 发表于 2013-10-16 19:35
输出的是j=1,i=0;与我预期的有点差别。

郁闷,刚才0写成1了
回复 使用道具 举报
麦者 发表于 2013-10-16 19:26
j没有被初始化,在构造函数里默认为0,因此++后为1,i被static修饰后始终为1,所以。。 ...

输出的是j=1,i=0;与我预期的有点差别。
回复 使用道具 举报
李江 发表于 2013-10-16 19:16
Test.getInstance();//这个获取的是一个对象,但是你没有接收它

//这个是调用内部的i,j,而不是上一步获取 ...

我注释掉Test.getInstance();这句话打印出来的还是j=1,i=0,按我的理解int型默认的是0,既然j ++ 了,j变成1了,i也应该是1,怎么会这样呢?
回复 使用道具 举报
1楼说的也对,但并不是单例的对象没被接受的问题
回复 使用道具 举报
本帖最后由 麦者 于 2013-10-16 19:39 编辑

j没有被初始化,在构造函数里默认为0,因此++后为1,i被static修饰后始终为0,所以。。
回复 使用道具 举报
Test.getInstance();//这个获取的是一个对象,但是你没有接收它

//这个是调用内部的i,j,而不是上一步获取对象的i,j
System.out.println("j = " + Test.j);
System.out.println("i = " + Test.i);
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马