构造器
每个对象都需要有个初始化方法,已保证每个类的域都能正确的初始化。
构造器方法怎么命名?
- 构造器方法的命名参考c++,与类名相同,并且没有返回值
- 调用构造是编译器的责任
方法重载
为什么需要方法重载
方法重载是解决方法名冲突的问题,如果方法名一样,编译器如何知道你调用的哪个方法
方法重载的定义
同一个类里,可以有同名的方法,但是必须,在以下一种一个条件
- 参数类型不通
- 参数列表长度不通
- 参数顺序不一致
满足其中一个,即可参数重载。
参数类型不一致的,编译器如何知道你调用的是哪个方法
默认可以向上转型,不可以向下转型。
public class test1 {
private String s;
public test1(String s) {
this.s = s;
}
public static void main(String[] args) {
int i = 100;
test2('i');
}
/**
*
* @param i
*/
private static void test2(long i){
System.out.println(i);
}
private static void test2(Integer i){
System.out.println(i);
}
private static void test2(Object i){
System.out.println(i);
}
}
分析:当传入的参数是int,但是没有定义接收int参数的方法时,编译器默认会向上转型去匹配方法,long->Ingeger->Object,如果有,方法也可以调用成功。
this关键字
this关键字的含义表示当前实例对象。
主要有两个作用:
- 命名冲突时,区分实例对象,和方法引用对象
- 复用类构造器
# this复用类构造器实例
public class thisDemo {
private String name;
private int code;
public thisDemo(String name) {
this.name = name;
}
public thisDemo(int code) {
this.code = code;
}
public thisDemo(String name, int code) {
this(name);
//this(code); //编译错误,构造器里只能调用一次构造器函数
this.code = code;
}
}
类的初始化顺序
- 父类的静态域以及静态代码块。静态域和静态代码块是按代码相对顺序,从上到下加载
- 子类的静态域以及静态代码块。
- 父类的成员域和构造函数
- 子类的成员域和构造函数
# 类加载顺序分析
public class StaticInitialzation {
public static void main(String[] args) {
System.out.println(" Crerating new Cupboard() in main");
new Cupboard();
System.out.println("===============================");
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("================================");
table.f2(1);
cupboard.f3(1);
}
static Cupboard cupboard = new Cupboard();
static table table = new table();
}
class Bowl{
public Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f1(int marker){
System.out.println("f1(" + marker + ")");
}
}
class table{
static Bowl bowl1 = new Bowl(1);
public table() {
System.out.println("table()");
bowl2.f1(1);
}
void f2(int marker){
System.out.println("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
public Cupboard() {
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int marker){
System.out.println("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
运行结果:
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Bowl(1)
Bowl(2)
table()
f1(1)
Crerating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
===============================
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
================================
f2(1)
f3(1)
分析:
- 首先初始化StaticInitialzation的静态域
- new Cupboard()时,不会重复加载Cupboard类,但是会加载Cupboard类的成员变量和构造函数。
- 方法只有在调用的时候才会加载
类的终结处理与回收
finalize方法
在实例被回收时,会调用类的finalize方法。但是在java中,gc是不稳定的,虚拟机只有在内存不足时,才会出发gc。因为gc本身会启动一些线程来工作,占用系统资源。
在工程实践中,一般会自定义类的destroy方法,用来关闭资源。不会依赖于finalize方法。