1、变量的定义
- 变量本质上是内存中的一块空间,这块空间有数据类型、有名字、有字面值
- 变量包含三部分:数据类型、名称、字面值【数据】
2、数据类型的作用
- 不同的数据有不同的的类型,不同的数据类型底层会分配不同的空间大小的空间。
- 数据类型是知道程序在运行阶段应该分配多大的内存空间。
注意:变量中存储的具体的“数据”必须和变量的“数据类型”一致,当不一致时编译报错
3、变量的作用域
3.1、作用域的概念
变量的作用域其实描述的就是变量的有效范围。在什么范围内是可以被访问的,只要出了这个范围该变量就无法访问了。简而言之就是,出了大括号就就不认识。
注意:在c语言中是允许出现嵌套式作用域时出现同名的变量,其作用域也遵循“出了括号不认识”这一原则。但是,在java中,如果出现此类嵌套作用域的同名变量,编译器会报告变量已经定义过,因为java设计者会认为这样做会导致程序混乱。此类嵌套情况只是针对于单个方法体内局部变量重名的嵌套,如果是成员变量与局部变量重名的情况,并不会报错
单个方法体内出现局部变量重名的嵌套:
//在c语言中,如下。
{/ 外层 i 的作用域
int i = 1;
/{//内层 i 的作用域,在此作用域内会屏蔽外层同名的变量 i
int i = 2;
//}/出了内层的括号之后,内层变量将失效,外层变量重新有效。
外层 i 的作用域
/}
全局变量和局部变量重名的情况:
//并不会报错
public class Variable03
{
static int k;
int i = 100;//成员变量
public static void main(String[] args)
{
int i = 10;//局部变量
System.out.println(i);
}
}
4、变量的声明
JAVA中的变量必须要先声明,再赋值,才能访问。而c语言中可以不初始化就进行访问, 得到的是一个垃圾值。但是在Java编程语法中,根本无法实现编译。 int i; 程序执行到这里,内存空间并没有开辟出来,变量i并没有初始化,所以没有赋值之前是无法访问的。
实例:
public class Variable{
public static void main(String[] args)
{
int i;
i = 100;
System.out.println(i);
}
}
5、变量的分类
根据变量声明的位置来分类:
- 局部变量
- 成员变量
5.1、 局部变量
在方法体当中声明的变量叫做局部变量。
注意:
- 局部变量在“方法体”中声明,局部变量在运行阶段内存在栈中分配。
- 局部变量必须初始化,java中是不会像c语言中一样给没有初始化的局部变量赋垃圾值。
- ==生命周期:==只在定义的方法体内有效。
5.2、成员变量
在方法体外,类体之内声明的变量叫做成员变量。
注意:
- 成员变量在堆中分配内存,由垃圾回收器回收。
- 成员变量可以不进行初始化,系统自动赋值默认值。
在不同的作用域中,变量是可以相同的,在同一个作用域中,变量不能重名,但是可以重新赋值。
5.2.1、实例变量
实例变量不能有static关键字,它同样具有一般成员变量的特点,其次,它还一定是被定义在JVM堆内存中的对象内。它是对象级别的变量。
注意:
- ==生命周期:==实例变量是随着对象的创建而存在的,随着对象的销毁而消失的。因此没有对象的创建就不存在实例变量。每一次新建对象都要为一个实例变量在堆内存中开辟空间。(并且同时在构造方法执行的时候完成初始化)
- 访问方式:
引用.
- 存储位置:堆内存
- ==使用场景:==所有对象都有这个属性,但是这个属性的值会随着对象的变化而变化【不同的对象的这个属性的值是不同的】
5.2.2、类变量(静态变量)
类变量需要用static关键字修饰,具有成员变量的基本特征,定义在方法体外,类体中。因此我们常说静态变量是类级别的。
注意:
- 生命周期: 类变量在类加载时就被分配了空间,即字节码文件被装载到类加载器时。直到JVM退出空间才被收回。
- 访问方式:
类名.
(同样也可以采用引用.的方式,只是本质上还是通过类进行访问的,即使引用是null也不会出现空指针异常) - ==存储位置:==方法区内存
- ==使用场景:==所有对象都有这个属性。并且所有对象的这个属性的值是一样的,建议定义为静态变量,以节省内存空间。