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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 胡宝林 中级黑马   /  2012-6-7 12:52  /  1782 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class C{
  static {
        a();
     }
     private static int sum;
     public static int getSum() {
         a();
         return sum;
     }
     
     private static boolean b = false;
     private static synchronized void a() {
         if (!b) {
             for (int i = 0; i < 100; i++)
                 sum += i;
             b = true;
         }
     }
}
public class D {
  public static void main(String[] args) {
  System.out.println(C.getSum());
}
}
//打印C类的getSum的返回值,会先加载C类,执行静态代码块中的代码,此时b为false,所以sum被增加到了4950
//并且加b置为了true,然后在执行getSum的时候,由于b为ttrue,就不会再给sum增加值,但是打印的结果是9900
//而不是4950,求解!!!

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
System.out.println(C.getSum());调用的时候,加载C类时先加载了static {a();} 静态代码块,这时候sum就等于4950;
再去调用private static synchronized void a(),经过了这个for()循环,sum就等于9900了,这么说能明白么?
回复 使用道具 举报
兄弟你这个题的主要问题是你没清楚静态代码块的执行顺序,一般一个类被调用时如果有静态代码块,静态代码块要先执行。想你这个你调用C类时因为C类中有静态代码块所以就先执行静态代码块,也就执行了一次a方法,加了一次,然后再调用getSun方法就有加了一次,所以结果为9900.
你这个题有两种改法,第一种:去除静态代码块。
  1. public class C{
  2.         /*  static {
  3.                 a();
  4.              }*/
  5.              private static int sum;
  6.              public static int getSum() {
  7.                  a();
  8.                  return sum;
  9.              }
  10.              
  11.              private static boolean b = false;
  12.              private static synchronized void a() {
  13.                  if (!b) {
  14.                      for (int i = 0; i < 100; i++)
  15.                          sum += i;
  16.                      b = true;
  17.                  }
  18.              }
  19. public class D {
  20.           public static void main(String[] args) {
  21.           System.out.println(C.getSum());
  22.      }
  23. }
复制代码
第二种去除getSum方法中调用a():
  1. public class D {
  2.           public static void main(String[] args) {
  3.           System.out.println(C.getSum());
  4.      }
  5. }

  6. public class C{
  7.           static {
  8.                 a();
  9.              }
  10.              private static int sum;
  11.              public static int getSum() {
  12.                  //a();
  13.                  return sum;
  14.              }
  15.              
  16.              private static boolean b = false;
  17.              private static synchronized void a() {
  18.                  if (!b) {
  19.                      for (int i = 0; i < 100; i++)
  20.                          sum += i;
  21.                      b = true;
  22.                  }
  23.              }
  24.         }
复制代码
回复 使用道具 举报
private static synchronized void a() {
         if (!b) {
             for (int i = 0; i < 100; i++)
                 sum += i;
             b = true;
         }
private static synchronized void a() {
         if (!b) {
             for (int i = 0; i < 100; i++)
                 sum += i;
             b = true;
         }
sum就等于4950后,if里面的条件语句ib=true而不是b=true,会执行for循环里面的语句,sum就会变成9900
回复 使用道具 举报
加载顺序问题,看着啊!main()->静态代码块->a()(b被置为true,这是你的疑惑吧!但是这时候还没有加载到b的定义那里。继续)->定义sum(这时候刚出静态代码块)->加载getSum->定义b,发现b存在了啊(静态加载的时候调用加载定义了)那我重新赋值吧,b=false->定义a(),a存在了->执行C.getSum();不知道 你能理解没有?
回复 使用道具 举报
关键是弄懂内部执行的顺序就可以解释了。只要把 private static boolean b = false;放在  static {        a();//     }的前面
其他不动就可以得到sum=4950.

public class C{
  static {
        a();//第一步静态代码块最先执行,a()中if(!b)成立执行,得sum=4950;b=true了程序继续往下执行
     }
     private static int sum;
     public static int getSum() {//第三步a()中if(!b)又成立执行,得sum=9900并返回
         a();
         return sum;
     }
     
     private static boolean b = false;//第二步:静态变量声明赋值先与静态方法执行,b再次赋值,b=false
    private static synchronized void a() {
         if (!b) {
             for (int i = 0; i < 100; i++)
                 sum += i;
             b = true;
         }
     }
}
public class D {
  public static void main(String[] args) {
  System.out.println(C.getSum());
}
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马