黑马程序员技术交流社区

标题: Java中关于static关键字方面的一点疑惑 [打印本页]

作者: 李俊伟    时间: 2013-3-1 00:22
标题: Java中关于static关键字方面的一点疑惑
先看如下代码:
public class BaseTest5 {

private String name;
private static int count1=10;
private int count2 = 10;

public static void main(String[] args) {
  BaseTest5 test = new BaseTest5();
  for(int i=0;i<10;i++){
   System.out.print(test.show1()+"  ");
  }
  System.out.println();
  for(int i=0;i<10;i++){
   System.out.print(test.show2()+"  ");
  }
}

public int show1(){
  return count1--;
}
public int show2(){
  return count2--;
}
}
打印结果为:
10  9  8  7  6  5  4  3  2  1  
10  9  8  7  6  5  4  3  2  1  

int型成员变量用static修饰和不用static修饰,在相同功能的函数中却返回了相同的打印结果。我本以为打印
结果的第二行会打印出:10  10  10  10  10  10  10  10  10  10,因为未被static修饰。
我的想法固然错了,那么static 关键字莫非在修饰成员变量时,在这种自增(自减)的函数运用中难道将变得毫无意义?可有可无?
或者我在上面的代码中还有什么不足的请指教。

作者: 夏晓彤    时间: 2013-3-1 00:46
楼主完全理解错误,没搞明白staitc的作用吧,我想你应该是和final搞混了,但是如果被final修饰编译能通过吗?
java Static 用法
有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。

声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。声明为static的方法有以下几条限制:
它们仅能调用其他的static 方法。
它们只能访问static数据。
它们不能以任何方式引用this 或super(关键字super 与继承有关,在下一章中描述)。

作者: 莫嘉伟    时间: 2013-3-1 00:59
楼主我也同意类上的哥们的看法你是不是想说final关键字啊,static的作用在你的代码里好像没啥体现,static就是指定一个变量是属于类,用static修饰的变量不能被对象访问,而且所有该类对象共享该属性。楼主的代码好像不是想验证static作用的感觉。
作者: 夏振博    时间: 2013-3-1 01:18
你的想法没错,static修饰后的属性为类属性只有一份,非static的属性为实例属性new几个对象就有几个实例属性,你的代码这创建了一个对象说明都只有一份
你的代码没有把这个特性表达出来,(我想也就是你想的),
这个代码是你想象的效果,没循环一次就创建一个对象,
  1. public class Demo {
  2.         private String name;
  3.         private static int count1 = 10;
  4.         private int count2 = 10;

  5.         public static void main(String[] args) {
  6.                 // Demo d = new Demo();
  7.                 for (int i = 0; i < 10; i++) {
  8.                         System.out.print(new Demo().show1() + "  ");
  9.                 }
  10.                 System.out.println();
  11.                 for (int i = 0; i < 10; i++) {
  12.                         System.out.print(new Demo().show2() + "  ");
  13.                 }
  14.         }

  15.         public int show1() {
  16.                 return count1--;
  17.         }

  18.         public int show2() {
  19.                 return count2--;
  20.         }
  21. }
复制代码

作者: 罗威    时间: 2013-3-1 01:19
哥们,第一:你必须了解static意义,它是随着类的加载就已经存在!跟你创建什么对象没有关系;你去看看关于内存分配的视频;
第二,你认为常量10不会变,若10真像你想的那样是固定不变的,那么你count2--编译时就会报错!
你可以改两个地方1:private  final int count2=10;2: return count2;试试! final表示最终的;
作者: 李俊伟    时间: 2013-3-1 13:31
谢谢大家的热心发帖!今天早上,经过一番调试,我又将我的程序做了相应的调整,得到了自己想要的结果。我把修改后的代码给大家看一看。

public class BaseTest5 {
       
        private static int count1=10;
        private int count2 = 10;
       
        public static void main(String[] args) {
                BaseTest5 test = new BaseTest5();
                for(int i=0;i<10;i++){
                        System.out.print(test.show1()+"  ");       
                }
                System.out.println();
                for(int i=0;i<10;i++){
                        System.out.print(test.show2()+"  ");       
                }
                System.out.println();
                BaseTest5 test1 = new BaseTest5();
                System.out.println(test1.show1());
                System.out.println(test1.show2());
        }
       
        public int show1(){
                return count1--;
        }
        public int show2(){
                return count2--;
        }
}
打印结果:
10  9  8  7  6  5  4  3  2  1  
10  9  8  7  6  5  4  3  2  1  
0
10
很神奇吧,创建新对象后,共享数据count1的初始值变为0了,非共享数据count2的初始值未改变。
也就是static修饰的成员变量,能被多对象调用,当共享数据发生改变时,下一对象调用该成员变量的初始值将是上一对象修改后的最终值。
未被static修饰的成员变量,无论创建多上个新对象,使用该成员变量的初始值还是count2 = 10。
作者: 李俊伟    时间: 2013-3-1 13:35
夏振博 发表于 2013-3-1 01:18
你的想法没错,static修饰后的属性为类属性只有一份,非static的属性为实例属性new几个对象就有几个实例属 ...

哥们,你的演示效果和我想要的结果一样,谢谢啦!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2