栈与堆
- 栈与堆是两种Java使用的内存空间;
- 实例变量是声明在类中方法之外的地方;
- 局部变量声明在方法或方法的参数上;
- 所有局部变量都存在于栈上相对应的堆栈块中;
- 对象引用变量与primitive主数据类型变量都放在栈上;
- 不管是实例变量或局部变量,对象本身都会在堆上;
构造函数
- 构造函数带有你在初始化对象时会执行的程序代码。也就是新建一个对象时就会被执行。
- 就算没有自己写构造函数,编译器也会帮你写一个(无参数,无内容的)。
public class Duck {
int size;
public Duck() { //没有返回类型
size = 27; //使用默认值
}
public Duck(int duckSize) {
size = duckSize;//使用参数设定
}
public static void main(String[] args) {
Duck d1 = new Duck();
Duck d2 = new Duck(24);
System.out.println("The size of d1 is " + d1.size);
System.out.println("The size of d2 is " + d2.size);
}
}
输出:
这个构造函数是重载的。
重载构造函数的意思是代表你有一个以上的构造函数且参数都不相同。(编译器只关注参数的类型和顺序,参数的名字不重要)
要点
- 实例变量保存在所属的对象中,位于堆上。
- 如果实例变量是个对对象的引用,则引用与对象都在堆上。
- 构造函数是在新建对象时执行的程序代码。
- 构造函数必须与类同名且没有返回类型。
- 可以用构造函数来初始化被创建对象的状态。
- 如果不写构造函数,编译器会自己创建一个,默认的构造函数没有参数。
- 实例变量有默认值,原始的是0/0.0/false,引用的默认值是null。
父类和继承与构造函数的关系
在创建新对象时,所有继承下来的构造函数都会执行。构造函数在执行的时候,第一件事是去执行他的父类的构造函数,一直连锁反映到Object类为止。
无参数的父类构造函数调用
public class Animal {
public Animal() {
System.out.println("Making an animal.");
}
}
public class Hippo extends Animal {
public Hippo() {
System.out.println("Making an Hippo.");
}
}
public class TestHippo {
public static void main(String[] args) {
Hippo h = new Hippo();
}
}
上面的例子是调用无参数的父类构造函数,可以交给编译器自行完成。
有参数的父类构造函数调用
public abstract 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);//传给Animal的构造函数
}
}
public class TestHippo {
public static void main(String[] args) {
Hippo h = new Hippo("Buffy");
System.out.println(h.getName());
}
}
输出:
Buffy
this()函数
- 使用this()来从某个构造函数中调用同一个类的另外一个构造函数。
- this()只能用在构造函数中,且必须是第一行语句。
- super()与this()不能同时用。每个构造函数可以选择调用super()或this(),但不能同时调用。