HeadFirst Java
本人有C语言基础,通过阅读Java廖雪峰网站,简单速成了java,但对其中一些入门概念有所疏漏,阅读本书以弥补。
第一章 Java入门
第二章 面向对象
第三章 变量
第四章 方法操作实例变量
第五章 程序实战
第六章 Java函数库
第七章 继承与多态
第八章 深入多态
第九章 构造器与垃圾收集器
栈与堆
栈(stack):方法调用和局部(栈)变量的生存空间
堆(heap):可垃圾回收的堆,是所有对象(实例变量在对象中)的生存空间
方法会被堆在一起
有关对象的局部变量
局部对象是某个对象的引用,只有变量本身会在栈上。对象仍在堆上!
实例变量
新建一个对象时,Java在堆上找一个足以存放该对象所有实例变量的堆空间。
主数据类型:int32位、long64位
引用变量:引用值所需的空间(即遥控器要的空间,而不是遥控器指向对象需要的空间)
创建对象
前文我们已经知道对象与变量的生存空间,那么对象如何诞生的?
构造函数
Duck duck = new Duck();,像是在调用方法,但并不是,只是new对象时会执行的特定代码。
- 初始化对象时会执行的代码。
- 没有写,编译器会自动写。
- 构造函数名与类相同,没有返回类型
重载与默认的构造函数 - 若写了有参数的构造函数,还需要无参数的,你必须手动写,编译器只会没有构造函数时补
- 如果类有一个以上构造函数,参数必须不同。这与方法的重载同理
参数不同的意思:与名字无关,与参数的类型、顺序有关!
父类、继承与构造函数的关系
创建某个对象时,对象会取得所有实例变量需要的空间,包括父类继承下来的
创建新对象时,所有继承下来的构造函数都会执行
- new启动构造函数的连锁反应
- 抽象类作为父类,构造函数也会在创建子类实例时执行
- 子类会根据父类的状态继承方法,完整的对象需要完整的父类核心,这是父类构造函数为何必须执行的原因
**具体的过程:**会不断调用父类的构造函数(通过super()),将其放入栈最上方,直到Object构造函数,接着不断执行其他父类构造函数,弹出。
如果没有调用super(),编译器会自动补上super();来调用父类的构造函数。
编译器只会自动调用无参数的构造函数
思考:小孩不能在父母前出生!虽然子类构造函数先调用,但却是最后完成的。因为必须先构造好父类,才能保证子类得以继承父类的状态与行为。所以说,super()函数的调用必然是所有构造函数语句的第一个语句!
有参数的父类构造函数
Hippo类继承了Animal类 getName()的方法,但没有继承私有的实例变量(指不能通过.进行访问,遥控只有控制对象外圈的按钮,但由前文可知构造这个对象时,构造子类,先在内圈构造了父类的内容,再在外圈继承、补充)。
也就是说,对象内环中Animal部分维持的name实例变量,可以通过继承的getName返回,问题在于要如何告诉Animal name的值呢?答案是:有参数的父类构造函数。从这才能将值存到父类的私有实例变量中!
public class Animal {
private String name;
public String getName(){
return name;
}
public Animal(String theName) {
name = theName;
}
}
public class Hippo extends Animal {
public Hippo(String name) {
super(name);//这里可以看到,我们将name值通过父类构造函数,传递给私有的实例变量
}
}
从某个构造函数调用 重载的 另一个构造函数
方法:使用this(),只能在构造函数的第一句,且与super()不能同时调用!
Class Mini extends Car {
Color colr;
public Mini() {
this(Color.Red);
}
public Mini(int size) {
this(Color.Red);
//super();不该再有super()!因为你要调用下一个构造函数就会构造父类!
}
public Mini(Color color){
super();
color = c;
//
}
对象的生命周期
局部变量 存活在声明该变量的方法中,方法结束时,也就死亡,且该变量可见范围只在所属的方法!
注意生命与范围不要搞混:
Life:变量栈块还在栈中,则局部变量存活
Scope:范围可能会转移到不可见的方法中,但不意味着局部变量死亡,回到该方法依旧可以使用
实例变量 可以理解为对象的一部分,寿命与对象相同,对象死了,实例变量跟着消亡。
若实例变量为引用变量,它指向的对象的生命周期 与 装着实例变量的对象无关哦,具体见下文杀手2
引用变量
引用变量如何影响对象的寿命?
——对象的唯一引用死了,对象就会被踢出堆,符合GC(garbage collect)条件,GC就会取消灭对象。
引用变量的使用同样有范围的限制(看是实例变量,还是局部变量)
杀死对象的三种方法:
1.引用永久离开它的范围 (作为局部变量,方法执行结束)
2.引用控制其他对象 P262
3.直接将引用指向空 (遥控器没有操控对象)