黑马程序员技术交流社区
标题: 静态变量和实例变量的小问题 [打印本页]
作者: 赵庆礼 时间: 2012-6-27 10:09
标题: 静态变量和实例变量的小问题
本帖最后由 赵庆礼 于 2012-6-28 14:13 编辑
public class StaticDemo
{
public static int staticVar = 0;
public int instanceVar = 0;
public StaticDemo()
{
staticVar++;
instanceVar++;
System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar);
}
}
看了之后还是不理解,谁能帮我仔细分析一下,谢谢
作者: 周朋飞 时间: 2012-6-27 10:15
这个就是静态变量与非静态变量的区别,静态变量是共有的,也就是说不管你创建多少个对象,静态变量只有一个,而普通对象是每个新创建的对象各自有一个,所以你每创建一个对象静态变量都会自加1 ,而普通变量每次创建完对象后在被赋值之前都是默认值 0 (基本类型)
作者: 郑森123 时间: 2012-6-27 10:20
静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量, 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。
由此看来, 一个变量可由static进行再说明,并改变其原有的存储方式。
1. 静态局部变量
在局部变量的说明前再加上static说明符就构成静态局部变量。
例如:
static int a,b;
static float array[5]={1,2,3,4,5};
静态局部变量属于静态存储方式,它具有以下特点:
(1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
(3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。
(4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜
2.静态全局变量
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。
静态变量
除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。
作者: 余清兰 时间: 2012-6-27 11:01
public class StaticDemo
{
public static int staticVar = 0; //静态变量是随着类的加载就存在于内存中,也称为类变量,是共享数据,都能直接使用类名来引用。
public int instanceVar = 0; //成员变量,就是对象的属性,只有被对象调用类后,才会分配空间存在于堆内存中,给对象的成员赋值。
public StaticDemo()
{
staticVar++;
instanceVar++;
System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar);
}
}
作者: Forever。 时间: 2012-6-27 16:28
首先你是要搞清楚静态变量和普通成员变量的区别所在:
静态变量和实例变量都可以用一个具体实例加.来引用。如 a.x; 静态变量还可以直接用类名加.进行引用 如 ClassName.x。静态变量和实例变量最大的区别是静态变量在内存中只有一份,所以该类的所有实例共享该变量;而实例变量随实例的不同可以不相同。
也就是说你可以建立N个StaticDemo的对象,当你没建立一次StaticDemo的对象的时候他的构造方法都会被执行一次,然而构造方法中有两个变量有变化,一个是被static修饰的staticVar;另一个是普通成员变量instanceVar。上面提到过,静态变量和实例变量最大的区别是静态变量在内存中只有一份,所以该类的所有实例共享该变量;而实例变量随实例的不同可以不相同。所以你每次建立一个对象staticVar就会+1,因为他是唯一的所有的对象公用着他,而instanceVar却是有多少对象就有多少。所以最终输出的结果一定是staticVar在不停的增大。+
作者: 刘笑 时间: 2012-6-27 17:41
由于静态变量在内存中是公用的(这也是静态变量存在的目的--共享),所以只创建一个,所以每次执行程序的时候都是自加1的;而实例变量与静态变量不同,对象每创建一次,就重新分配一个内存空间,并初始化为0;楼主明白了吗?
补充:
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。
public class Temp {
int t; //实例变量
public static void main(String args[]){
int t=1; //局部变量
System.out.println(t); //打印局部变量
Temp a= new Temp(); //创建实例
System.out.println(a.t); //通过实例访问实例变量
}
}
结果为:
1
0 (成员变量具有缺省值 而局部变量则没有)
把代码改为
public class Temp {
static int t; //类变量
public static void main(String args[]){
System.out.println(t); //打印类变量
int t=1; //局部变量
System.out.println(t); //打印局部变量
Temp a= new Temp(); //创建实例
System.out.println(a.t); //通过实例访问实例变量
}
}
结果则为
0
1
0
静态变量static是一个公共变量,无论哪个对象改变了它的值,对其他所有该类对象都有效。静态变量的一个重要作用是当作同类各个对象之间传递信息使用,类似于C语言中的全局变量。但这样破坏了数据的封装原则,往往会留下隐患,所以使用这类变量时需要万分谨慎。
作者: 赵庆礼 时间: 2012-6-28 14:11
刘笑 发表于 2012-6-27 17:41
由于静态变量在内存中是公用的(这也是静态变量存在的目的--共享),所以只创建一个,所以每次执行程序的时 ...
谢谢,现在明白了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |