导读:最近做的一个项目,因为声明的变量位置不对,然后名字也没有对上,结果导致系统的参数值无法传递,造成了一个功能性的错误。以前,也没有注意到这一点,现在学习J2SE,将这一点做一个简单的总结,为以后的学习,积累点基础知识!
一、分类
数据根据其可变性,可分为常量和变量。常量:在一个过程中,固定不变的量。变量:在一个过程中,可以取不同数值的量。
说明:在Java中,或者说在别的语言中(大同小异),按照变量被声明的位置来划分,可以将其分为成员变量、局部变量、全局变量三个类别。其中,成员变量在类体中声明,应用于整个类。局部变量是一个方法的形参,在方法内部,或者在一个代码块内部声明的变量。全局变量,则运用与整个系统,在使用全局变量的时候,一定要慎重。
而按照其变量的所属类别,又可以将变量分为基本数据类型变量和引用类型变量。
注意:在java里面,没有所谓的全局变量的概念,但是可以通过public static来定义一个变量,使其具有全局变量的作用。也可以写一个具体的类,在类里面定义一些变量,声明其变量和类的访问权限,以达到全局变量的作用。
PS:为什么java里面没有全局变量的概念,却提供了类似全局变量的静态变量?为什么别的语言,比如说C、C++、VB等有全局变量,跨平台性不高?
二、内存中存储
一个程序被写出来,一直到运行,在这期间,程序所携带的数据又是怎样存储的呢?首先看一个程序的执行过程:
在查资料中,java一共分配了6个内存区域,分别是:
寄存器:在程序中无法控制
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
堆:存放用new产生的数据
静态域:存放在对象中用static定义的静态成员
常量池:存放常量
非RAM存储:硬盘等永久存储空间
上图是程序在运行过程中的数据的内存分布,一个程序的运行,经过编译、下载、解释、执行几个步骤,那么在程序未执行的时候,它的存储,又是在哪里?经过查资料,请看下图 :
问题 :代码段,数据段,栈,堆,这些都还能理解,但是,常量池为什么也存到了堆中?常量不应该像静态变量一样,存放在数据段吗?而Java将内存分配了6个区域,这6个区域是单独的个体区域,还是说像堆一样,在一个区域里面,又接着分类?
三、疑惑和思考
在学习变量这一块的时候,我测试了以下代码
<span style="font-family:KaiTi_GB2312;font-size:18px;"> static void Main(string[] args) { int a = 3; int b = 3; int c = b = 4; Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); }</span>
其运行结果为:3,4,4
问题:在这之中,定义了b=3,这一行代码是不是根本就没有在内存存在过?
紧接着,又做了另外的一个尝试:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> class Program { static void Main(string[] args) { int a = 3; Console.WriteLine(a); int b = 3; Console.WriteLine(b); int c = b = 4; Console.WriteLine(b); Console.WriteLine(c ); } }</span>其运行结果为:3,3,4,4
这就说明,其实这b=3这一行代码,或者说对b赋值3,这一个工作,确实是在内存中存在过的,那么后来的b变成了4,在内存中,又是怎么体现的?
猜想:当对a赋值时,在内存中开辟了一块值为3的空间,而当令b=3时,在这里并没有再开辟3的空间,而是直接指向了a的地址空间。后面,当对b赋值4的时候,在内存中取消了b对其3的指向引用,而单独开辟了一块为4的空间,同理,c=b也是同样的道理。
结论:在内存中,当我们定义常量或者变量时,首先是去寻找是否已经存在相应的值,如果存在则不必要开辟一块存储空间,而是添加地址引用,而不存在时,则开辟?那在本例中,如果将其a的值更改为5,其b的值会是5还是最开始的3,在这之间,发生了什么?
四、感受
虽然没有解决很多问题,但是记录了问题,我同样很开心。而且,最近发现自己,比以前更爱去做一些尝试了,加油。