栈与堆
栈: 栈是方法调用及局部变量的生存空间。局部变量和方法的参数都是声明在方法中,它们是暂时的,其生命周期只限于方法被放在栈上的期间,也就是方法调用至执行完毕为止。
堆: 堆又称为可垃圾回收的堆,是对象生存的空间。
注意:1.实例变量是被声明在类中,而不是方法里面。因此,实例变量存在于所属的对象中,即实例变量在堆上。
2.局部变量如果是一个对对象的引用,则只有变量本身会放在栈上,对象永远都只在堆上。
方法调用: 当方法被调用时,它会在调用栈的栈顶,直到执行完毕。
①调用doStuff()
②doStuff()调用go()
③go()调用crazy()
④crazy()执行完毕,go()又回到栈顶
构造函数
构造函数带有初始化对象时会执行的程序代码,唯一能调用构造函数的办法就是新建一个类,构造函数名称一定要与类的名称相同。就算没有自己写构造函数,编译器也会帮你写一个。
构造函数与方法的区别: 方法有返回类型,构造函数没有返回类型。
自己编写构造函数的意义在于,构造函数让你有机会可以介入new的过程。
带参数的构造函数
如果某种对象在初始化时就应该设定状态,最好的方法是把初始化的代码放在构造函数中,并把构造函数设定为需要参数的。
如果你已经写了一个有参数的构造函数,并且你需要一个没有参数的构造函数,你必须自己在写一个无参数的构造函数。
如果类有一个以上的构造函数,则参数一定要不一样。
父类的构造函数
1.在创建新对象时,所有继承下来的构造函数都会执行。
2.调用父类构造函数的唯一方法是调用super()。在构造函数中调用super()会把父类的构造函数放在堆栈的最上方。父类的构造函数又会调用它的父类构造函数,一直到Object的构造函数为止。
3.如果我们没有调用super(),编译器会帮我们加上super()的调用,但编译器帮忙加的一定是没有参数的版本。
4.要调用父类的有参数构造函数,必须要用super()来引用,括号中带上相应版本的参数。
this()
1.使用this()来从某个构造函数调用同一个类的另外一个构造函数。
2.this()只能用在构造函数中,且必须是第一行语句。
3.super()与this()不能兼得。
对象的生命周期
1.局部变量只会存活在声明该变量的方法中。
局部变量的life与scope:
life:活到方法执行完毕为止
scope:局部变量的范围只限于方法内,当次方法调用其他方法时,变量还活着但不在范围,其他方法执行完毕后返回时,范围也就回来了。
2.实例变量的寿命与对象相同。如果对象还活着,则实例变量也会活着。
3.当最后一个对对象的引用消失时,对象就会变成可回收的。
①引用永久性离开它的范围。
②引用被赋值到其他对象上。
③直接将引用设定为null。