黑马程序员技术交流社区

标题: 关于全局变量的小疑问 [打印本页]

作者: 梁志冰    时间: 2012-9-20 21:20
标题: 关于全局变量的小疑问
class FinalDemo
{
public static void main(String[] args)
{
  System.out.println(Person.country);
  System.out.println("over");
}
}
class Person
{
    public static final String country="cn";
private String name;
private int age;
Person(String name,int age){
  this.name=name;
  this.age=age;
}
}
程序1

class FinalDemo
{
public static void main(String[] args)
{
    System.out.println("over");
}
}
class Person
{
    public static final String country="cn";
private String name;
private int age;
Person(String name,int age){
  this.name=name;
  this.age=age;
}
}
程序2

问题:
1、程序1中当运行完System.out.println(Person.country);语句后,变量country还在内存中吗?
2、程序2中,变量country进入过内存中吗?



作者: 史小兵    时间: 2012-9-20 21:38
你定义的country是静态的变量,因此其实属于类的,当你加载类时就会加载这些静态信息!这些信息存放在堆内存之中。
因此System.out.println(Person.country);后内存中还有该静态信息。
程序2中,变量country进入过内存中吗?
答案是进入了!
直到程序结束才会被释放!
作者: 梁志冰    时间: 2012-9-20 21:47
史小兵 发表于 2012-9-20 21:38
你定义的country是静态的变量,因此其实属于类的,当你加载类时就会加载这些静态信息!这些信息存放在堆内 ...

country变量是静态的全局变量,应该是存储在内存中数据共享区中吧,?程序2中的Person我都没有调用过,怎么会在内存中呢?您能不能说得详细一点?
作者: 史小兵    时间: 2012-9-20 22:06
内存分为对内存和栈内存,和方法区;
堆内存之中存放的一般都是一些对象,但是不存放基本的数据类型!
栈内存之中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中。
方法区中存放的都是静态变量,被所有的线程共享。
程序2中的Person我都没有调用过,怎么会在内存中呢?
因为当你创建类的对象时,就得加载该类相关的信息吧,这些静态的信息就是在这个时候被加载进去的!
作者: 张忠豹    时间: 2012-9-20 22:24
答案是二者都存在于内存中的。
首先,对于程序1而言,要说的是country变量,是静态的,静态的变量是随着类的加载而加载,其存在于方法去的共享区中,至于sysout语句执行完以后,可以说country还是会在的,因为虽然此时没有和Person类进行交互了,但是该静态变量所属于类的。Java中有内存管理机制,JVM虚拟机会在不定时的情况下检查,看看该类的实例有没有引用指向了,虽然此时没有实例,但是该类的字节码是实实在在存在于内存中的。
其次,对于程序2而言,亦是如此啊,该变量是属于类的,存在于方法去的共享区中,虽然没有调用,但是该类的字节码的字节码文件是实实在在存在的。
作者: 梁志冰    时间: 2012-9-20 22:55
张忠豹 发表于 2012-9-20 22:24
答案是二者都存在于内存中的。
首先,对于程序1而言,要说的是country变量,是静态的,静态的变量是随着类 ...

这个程序2中也进内存吗?问题是我都没有对Person类进行过任何的操作呀?假设它也进内存的话,我有这样的一个构想,一个项目中,定义的很多个全局变量,那程序一加载,方法共享区中不就被全局变量占用了很大一部分内存了吗?
作者: 张忠豹    时间: 2012-9-20 23:33
是啊,只要你的java虚拟机启动,并编译了类成功,该类就会进入内存。当时Java中不是有内存管理机制,这就是java语言的高明之处啊,你考虑的问题sun公司早就考虑到了,所以便有了Java虚拟机的出现,通俗的说,它可以在不定时的情况下,对内存中的数据进行检查,如果发现一个类在很长时间都没有引用的话,那么它就会释放掉该类所占用的内存空间,当然程序员也可以手动来实现释放内存的效果,调用System.gc()方法来运行垃圾回收器,进行垃圾回收动作。
作者: 史小兵    时间: 2012-9-20 23:34
全局变量在整个工程文件内都有效;全局变量本身就是采用静态存储方式,   当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
但是你要知道,定义全局变量就是为了共享,对于需要在整个工程共享的我们才会定义为全局变量!如果真的需要定义大量的全局变量,是会很占内存!所以在开发时应该注意这一点!
作者: 梁志冰    时间: 2012-9-21 07:13
谢谢各位的解答,了然啦
作者: 夏天    时间: 2012-9-21 07:48
梁志冰 发表于 2012-9-21 07:13
谢谢各位的解答,了然啦

有深度,你懂得~~
作者: 王小闲7    时间: 2012-9-21 08:57
梁志冰 发表于 2012-9-20 21:47
country变量是静态的全局变量,应该是存储在内存中数据共享区中吧,?程序2中的Person我都没有调用过,怎 ...

静态的全局变量,不需要创建对象就必须加载所以程序2中person即使没有调用过也在内存中




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