构造器与垃圾收集器
栈与堆:生存空间
在Java中,在乎内存的两种区域:对象的生存空间堆(heap)和方法调用及变量的生存空间(stack)。
实例变量是被声明在类而不是方法里面。它们代表单独对象的“字段”。实例变量存在所属的对象中。
下面 i 就是实例变量。
public class Test {
int i;
}
局部变量和方法的参数都是被声明在方法中。它们是暂时的,且生命周期只限于方法被放在栈上的这段时间。
下面 a 和 b 就是实例变量。
public void test(int a) {
int b = a + 1;
}
当调用一个方法时,方法会被放在调用栈的栈顶。它带有方法的状态,包括执行到哪一行程序以及所有的局部变量的值。栈顶上的方法是正在执行的方法。
例如
public void first() {
int i = 4;
second(4);
}
public void second(int a) {
int b = a + 1;
third();
}
public void third() {
boolean c = false;
}
栈内情况如下
要点
- 栈和堆两种内存空间。
- 实例变量声明在类中,局部变量声明在方法或方法的参数上。
- 所有局部变量都存在与栈上对应的堆栈块中。
- 实例变量保存在所属的对象中,位于栈上。
- 不管是实例变量还是局部变量,对象本身都会在堆上。
构造器
构造函数在初始化对象时会执行的程序代码,也就是new对象时执行。默认编译器会实现一个无参的构造函数。
例如
Test test = new Test();
也可以自己重载构造函数
public class Test {
int i;
public Test() {
}
public Test(int x) {
}
public Test(int x, int y) {
}
}
要点
- 构造函数必须与类同名且没有返回类型。
- 无构造函数时,编译器会实现一个无参的构造函数。
- 重载构造函数也需要遵循重载规则。
父类以及继承与构造函数之间的关系
每个父类都有一个构造函数,且每个构造函数都会在子类对象创建时期执行。
对象的生命周期
对象的生命周期要看引用变量的生命周期而定。
局部变量只会存活在声明该变量的方法中。
实例变量的寿命与对象相同。如果对象还活着,则实例变量也会是活的。
有三种方式可以释放对象的引用:
- 引用永久性离开它的范围。
test会在方法结束时消息。
public void toDo() {
Test test = new Test();
}
- 引用被赋值到其他对象上。
第一个对象会在test被赋值时变成可回收的状态。
Test test = new Test();
test = new Test();
- 直接将引用设定为null。
Test test = new Test();
test = null;