#默认构造器
默认构造器(又名"无参构造器")是没有形式参数的——它的作用就是创建一个“默认对象”。如果类当中没有默认构造器,编译器会自动帮你创建一个默认构造器。例如:
class Apple {}
public class DefaultConstructor {
public static void main(String args[]) {
Apple a = new Apple();
}
}
表达式 new Apple() 创建了一个新对象,并调用其默认构造器——即使你没有明确的去定义它。但是如果已经定义了一个构造器(无论有无参数),编译器都不会再自动帮你创建默认的构造器了。
public class Pear {
Pear(int i){
}
Pear(String s){
}
}
public class PearTest {
public static void main(String args[]){
//Pear p = new Pear(); //这样写编译器就会报错
Pear p1 = new Pear(1);
Pear p2 = new Pear("ss");
}
}
就好比编译器当你没有定义构造器的时候,他会觉得:“你需要一个构造器,我来帮你创建”。
但是当你自己定义了构造器之后,他会觉得:“看来你已经知道你要做什么了,我不需要帮你创建了”。
this关键字
public class Banana {
void peel(int i){}
}
public class BananaPeel {
public static void main(String[] args) {
Banana a = new Banana();
Banana b = new Banana();
a.peel(1);
b.peel(2);
}
}
这里两个对象都调用了peel()方法,编译器是如何知道是被a调用还是被b调用的呢?
为了能用简便,面向对象的语法来编写代码——“发送消息给对对象”,所以编译器做了一些幕后的工作,它暗自把所操作的对象的引用作为了第一个参数传给了peel()。所以上面两个方法其实是这样:
Banana.peel(a,1);
Banana.peel(b,2);
这是内部的形式,我们外部并不能这样书写代码,但可以通过这种写法来了解实际所发生的事情。
如果你希望在方法的内部获得对当前对象的引用,就可使用关键字this。
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可。当前方法中的this引用会自动应用于同一类中的其他方法。
public class Rule {
void pick() {
}
void pit() {
pick();
}
}
在pit()内部,你可以写this.pick(),但无此必要。编译器能自动为你添加。只有当需要明确指出当前对象的引用时,才需要使用this关键字。例如,返回对当前对象的引用:
public class Leaf {
int i=0;
Leaf increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
public static void main(String args[]) {
Leaf l = new Leaf();
l.increment().increment().increment().print();
}
}
Output: i=3
由于increment()通过this关键字返回了对当前对象的引用,所以很容易在一条语句里对同一个对象执行多次操作。
public class Person {
public void eat(Apple apple) {
Apple peeled = apple.getPeeled();
System.out.println("yummy");
}
class Peeler {
static Apple peel(Apple apple){
return apple;
}
}
class Apple {
Apple getPeeled() {
return Peeler.peel(this);
}
}
public class PassingThis {
public static void main(String[] args) {
new Person().eat(new Apple());
}
}
}
Output: Yummy
Apple需要调用Peeler.peel()方法,他是一个外部的工具方法,将执行由于某种原因而必须放在Apple外部的操作(可能是因为该方法需要多次调用,避免重复这些代码)。为了将其自身传递给外部方法,Apple就可使用this关键字。
如果一个类中谢了多个构造器,可能想在一个构造器中调用另外一个构造器,可用this关键字做到这点。
通常写this的时候,都是指“当前对象”,而且它本身表示对当前对象的引用。在构造器中,如果为this添加了参数列表,那么就有了不同的含义。这将产生对符合此参数列表的某个构造器的明确调用。
public class Flower {
int petalCount = 0;
String s = "initial value";
Flower(int petals){
petalCount = petals;
System.out.println("此构造器只有int参数列表,petalCount = " + petalCount);
}
Flower(String str){
s = str;
System.out.println("此构造器只有String参数列表,s = " + s);
}
Flower(String s, int petals){
this(petals);
//this(s); 尽管可以用this调用构造器,但却不能调用两个,而且必须将构造器置于方法起始处,否者编译器会报错!
this.s = s;
System.out.println("此构造器有String和int参数列表");
}
Flower() {
this("hi",47);
System.out.println("无参构造器");
}
void printPetalCount() {
//this(11); 除构造器外,编译器禁止在其他任何方法中调用构造器
System.out.println("petalCount = " + petalCount + " , s = " + s);
}
public static void main(String[] args) {
Flower x = new Flower();
x.printPetalCount();
}
}
Output:
此构造器只有int参数列表,petalCount = 47
此构造器有String和int参数列表
无参构造器
petalCount = 47 , s = hi
这个例子夜展示了this的另一种用法。由于参数s的名称和数据成员s的名称相同,所以容易产生歧义。使用this.s 来代表数据成员就能解决这个问题。在java程序代码中也经常出现这种写法。
引用自《Think in java》