变量
--------------------------------------------------------------------------------
1. 变量定义和特点
定义:
内存中的一个存储区域.
该区域有自己的名称(变量名)和类型(数据类型).
该区域的数据可以在同一类型范围内不断变化.
特点:
变量其实就是将不确定的数据进行存储, 也就需要在内存中开辟一个空间.
如何开辟空间呢? 就是通过明确数据类型和变量名称来完成.
变量只能存放某一类型的数据.
--------------------------------------------------------------------------------
2. 为什么要定义变量/定义变量的意义
用来不断的存放同一类型的常量值, 并可以重复使用
理解: 变量就如同数学中的未知数.
--------------------------------------------------------------------------------
3. 何时定义变量?
当数据的值不确定, 需要对数据进行存储的时候就定义一个变量来完成存储动作.
--------------------------------------------------------------------------------
4. 如何定义变量?
变量的定义格式:
数据类型 变量名 = 初始化值;
注: 格式是固定的. 记住格式, 以不变应万变
3要素: 数据类型 + 变量名 + 初始化值(以及作用范围)
--------------------------------------------------------------------------------
5. 修饰符 Modifiers
成员变量修饰符:
FieldModifier: one of
Annotation public protected private
static final transient volatile
局部变量修饰符:
VariableModifier: one of
Annotation final
变量与 final 修饰符
不被 final 修饰, 可以赋值多次, 初始化后还能改变其值.
被 final 修饰的变量, 只能赋值1次, 也即初始化后就不能改变其值
局部变量被内部类使用时必须被 final 修饰, 否则编译错误.
final 成员变量不会被编译器默认初始化, 必须手动初始化, 否则编译错误.
被 final 修饰的实例变量, 若声明时未初始化,
则(1)要么在构造代码块初始化(2)要么在每一个构造函数中分别初始化
被 final 修饰的类变量, 若声明时未初始化, 则必须在静态代码块中初始化.
一个类可以有多个构造代码块, 而各构造代码块按声明的顺序先后执行.
所以, 前面的构造代码块初始化了 final 实例变量, 后面的构造代码块才能使用,
而且后面的构造代码块不能再更改其值
静态代码块与构造代码块同理.
一个类可以有多个静态代码块, 而各静态代码块按声明的顺序先后执行.
所以, 前面的静态代码块初始化了 final 类变量, 后面的静态代码块才能使用,
而且后面的静态代码块不能再更改其值
final 变量为常量. 分为局部常量, 实例常量和类常量.
实例常量和类常量的名字应该按常量名的命名规则编写.
--------------------------------------------------------------------------------
6. 变量的初始化
变量必须被初始化后才能使用!!!
使用未被初始化的变量将导致编译错误
声明一个变量后, 必须用赋值语句对变量显示初始化, 千万不要使用未被初始化的变量.
成员变量的初始化
非 fianl 成员变量会被编译器默认初始化.
final 成员变量不会被编译器默认初始化, 必须手动初始化
对 final 成员变量的初始化见"变量与 final 修饰符"
局部变量的初始化
局部变量必须手动初始化.
而且, 声明局部变量时应立即初始化, 避免使用了未被初始化的变量导致编译错误.
对 final 局部变量的初始化见"变量与 final 修饰符"
public class Demo {
// 编译器不会自动初始化被 final 修饰的成员变量, 必须手动初始化
// private final String nationality; // 编译错误. final 成员变量必须手动初始化
private final String nationality = "cn";
public static void main(String[] args) {
// int num; // 局部变量定义时未初始化, 易出错
// System.out.println(num); // 编译错误: 使用未初始化的变量
int num = 5; // 局部变量定义时未初始化, 易出错
// System.out.println(num); // ok
}
}
--------------------------------------------------------------------------------
7. 变量的作用域
变量的作用域: 声明变量的一对{}之间.
具体情况如下:
声明在语句块中的变量, 其作用域为该语句块; // 局部变量
声明在函数中的变量, 其作用域为该函数; // 局部变量
声明在构造代码块中的变量, 其作用域为该构造代码块; // 局部变量
声明在静态代码块中的变量, 其作用域为该静态代码块; // 局部变量
声明在局部代码块中的变量, 其作用域为该局部代码块; // 局部变量
(局部代码块可以出现在语句块中, 函数中, 构造代码块中, 静态代码块中)
声明在类成员位置上的变量, 其作用域为整个类. // 成员变量
局部变量必须声明到局部位置(如语句块, 函数, 构造代码块, 静态代码块中),
不能直接声明到类中, 否则转变成了成员变量.
局部变量的作用域为语句块的作用域, 函数作用域, 构造代码块作用域或者静态代码块的作用域.
成员变量作为类的成员, 必须直接声明到类中, 其作用域为整个类;
(所有函数肯定都必须是某一个类的成员函数, 因此函数必须直接声明到类中)
局部位置: 包括语句块中, 函数中, 构造代码块中, 静态代码块中.
--------------------------------------------------------------------------------
8. 使用变量的注意事项
变量的作用范围(一对{}之间有效)
初始化
--------------------------------------------------------------------------------
9. 局部变量和成员变量比较
作用域比较
局部变量必须声明到局部位置(如语句块, 函数, 构造代码块, 静态代码块中),
不能直接声明到类中, 否则转变成了成员变量.
局部变量的作用域为语句块的作用域, 函数作用域, 构造代码块作用域或者静态代码块作用域.
成员变量作为类的成员, 必须直接声明到类中, 其作用域为整个类;
(所有函数肯定都必须是某一个类的成员函数, 因此函数必须直接声明到类中)
在局部变量作用域内, 局部变量优先级高于成员变量.
即当局部变量名与某成员变量相同时, 该成员变量在局部变量作用域内无效.
此时, 用this.成员变量表示该成员变量, 将其与局部变量区分开来.
在嵌套的作用域内, 不允许出现同名的局部变量.
也即绝对不允许同名局部变量的作用域出现重叠. 否则, 编译错误.
初始化比较
成员变量的初始化
非 fianl 成员变量会被编译器默认初始化.
final 成员变量不会被编译器默认初始化, 必须手动初始化
局部变量的初始化
局部变量必须手动初始化.
而且, 声明局部变量时应立即初始化, 避免使用了未被初始化的变量导致编译错误.
***被 final 修饰的变量的初始化见"变量与 final 修饰符"
修饰符比较
FieldModifier: one of
Annotation public protected private
static final transient volatile
VariableModifier: one of
Annotation final
变量与 final 修饰符
局部变量被内部类使用时必须被 final 修饰, 否则编译错误.
final 成员变量不会被编译器默认初始化, 必须手动初始化, 否则编译错误.
***被 final 修饰的变量的初始化见"变量与 final 修饰符"
在内存中存储位置的比较
实例变量存在于堆内存中, 因为对象的存在, 才在内存中存在.
类变量存在于方法区中, 随着类的加载而加载, 随着类的消失而消失.
局部变量仅仅存在于栈内存中(包括方法, 构造代码块, 静态代码块中的局部变量)
--------------------------------------------------------------------------------
|
|