变量
成员变量和局部变量
根据定义变量位置的不同,可以将变量分为成员变量和局部变量:
- 成员变量是在类范围内定义的变量;
- 成员变量无需显式初始化,系统会自动对其进行默认初始化。
- 局部变量是在一个方法内定义的变量。
- 形参:在整个方法内有效;方法局部变量:从定义这个变量开始到方法结束这一段时间内有效;代码块局部变量:从定义这个变量开始到代码块结束这一段时间内有效。
- 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
- 局部变量除了形参外,都必须显示初始化,也就是要指定一个初始值,否则不能访问。
- 局部变量是在栈上分配的。
/**
* 成员变量和局部变量
* @author chenzufeng
*/
public class VariableTest {
/**
* 成员变量
*/
public static String staticName = "类属性";
public String noneStaticName = "实例属性";
/**
* 未初始化的成员变量
*/
public static String staticNameWithoutInit;
public String noneStaticNameWithoutInit;
/**
* 在方法中定义一个局部变量并试图输出:
* int i; System.out.println(i);
* 由于没有初始化,故无法输出
*/
public void testVariable() {
int i = 1;
System.out.println(i);
}
/**
* 定义一个静态方法
*/
public static void testStaticMethod() {
int i = 2;
System.out.println(i);
}
public static void main(String[] args) {
/**
* 1. 类属性和实例属性的范围一样吗?
* 在没创建实例之前,可以调用类属性,但不能调用实例属性;
* 实例化对象之后,就可以调用实例属性了。
*/
// 输出:类属性
System.out.println(VariableTest.staticName);
VariableTest test = new VariableTest();
// 输出:实例属性
System.out.println(test.noneStaticName);
/**
* 2.成员变量需要显性初始化吗?
* 不需要:成员变量会自动隐性初始化,赋给变量一个默认值
*/
// 直接调用没有初始化的类属性,输出null
System.out.println(VariableTest.staticNameWithoutInit);
// 用实例化对象调用没有初始化的实例属性,输出null
System.out.println(test.noneStaticNameWithoutInit);
// test.testVariable
VariableTest.testStaticMethod();
}
}
/**
* 局部变量覆盖成员变量
* @author chenzufeng
*/
public class VariableTest {
/**
* 当实例变量与方法中的局部变量同名时,局部变量的值会覆盖实例变量
*/
public String city = "南京";
private static String localCity = "扬州";
public void cover() {
/**
* 方法中的同名局部变量会覆盖实例变量
* 但
* city = "杭州";
* System.out.println(city); 杭州
* System.out.println(this.city); 杭州
*/
String city = "杭州";
// 输出:杭州
System.out.println(city);
// 输出:南京
System.out.println(this.city);
}
public static void main(String[] args) {
System.out.println(localCity);
// System.out.println(city); 无法访问city
localCity = "杭州";
System.out.println(localCity);
/**
* 重新创建名为localCity和city的String类
*/
String localCity = "上海";
String city = "北京";
new VariableTest().cover();
}
}
实例变量和类变量
成员变量可以分为:
- 实例属性(不用static修饰)
- 随着实例的存在而存在;
- 当一个对象被实例化之后,每个实例变量的值就跟着确定;
- 实例变量具有默认值:
- 数值型变量的默认值是
0
,布尔型变量的默认值是false
,引用类型变量的默认值是null
。 - 变量的值可以在声明时指定,也可以在构造方法中指定。
- 数值型变量的默认值是
- 存储在堆!
- 类属性(static修饰)
- 随着类的存在而存在;
- 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
- 存储在方法区!
- 静态变量除了被声明为常量外很少使用,静态变量是指声明为
public/private
、final
(不可改变)和static
(独一份)类型的变量。