java默认构造器以及this关键字

#默认构造器

默认构造器(又名"无参构造器")是没有形式参数的——它的作用就是创建一个“默认对象”。如果类当中没有默认构造器,编译器会自动帮你创建一个默认构造器。例如:

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》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值