引言:
D五、java方法重载中我们在最后提到,同一类型的两个对象是怎么调用一个方法的呢?那么我们来看看这个例子吧
一、this
class cat{
void print(int i) {
System.out.println("There is "+i+" cat.");
}
}
public class ThisObject {
public static void main(String []args) {
cat c1 = new cat();
cat c2 = new cat();
c1.print(1);
c2.print(2);
}
}
可能你会发现,这两个对象是通过参数来调用的(就是把所操作对象的引用传递给方法)。如果希望在方法的内部获得对当前对象的引用,那么我们就必须知道this关键字。this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。如果在方法里面调用同一个类里面的方法,则不需要使用this关键字,this引用会自动的应用于同一类中的方法。所以,只有需要明确指出当前对象的引用的时候,才需要用到this关键字。例如:
public class ThisObject {
int i = 0;
ThisObject cat() {
i++;
return this;
}
void print() {
System.out.println("i= "+i);
}
public static void main(String []args) {
ThisObject t = new ThisObject();
t.cat().cat().cat().print();
}
}
输出结果: i= 3
这里我们就需要明确返回当前对象的引用(这样可以在一条语句里面对同一对象执行多次操作),所以就在return后面用到了this关键字。this关键字也可以用于将当前对象传递给其它方法。例如:
class cat{
public void eat(Apple apple) {
Apple peeled = apple.getPeeled();
System.out.println("jack");
}
}
class Peeler{
static Apple peel(Apple apple) {
return apple;
}
}
class Apple{
Apple getPeeled() {return Peeler.peel(this);
}
}
public class ThisO {
public static void main(String []args) {
new cat().eat(new Apple());
}
}
输出: Jack
我们在主方法里面创建了cat的对象,并且调用里面的eat方法,参数是Apple的对象,在里面又调用了Apple里面的getPeeled()方法,需要返回当前对象引用,然后在返回apple对象,最后输出jack。这个例子简单来说就是Apple需要调用外部的Peeler.peel方法,需要将自身传递给外部方法,所以我们就用到了this关键字。当然啦,我们也可以用this关键字在构造器中调用构造器(只能调用一个构造器)。例如:
public class ThisO{
int Count = 0;
String s = "cat";
ThisO(int c){//int参数的构造器
Count = c;
System.out.println("Constructor int args Count = "+c);
}
ThisO(String ss){//String 参数的构造器
System.out.println("s = "+ ss);
s = ss;
}
ThisO(String s,int c){//两个参数的构造器
this(c);
//this(s);试图调用另一个构造器,错误!
this.s = s;//明确对数据成语进行赋值,与参数s区别
System.out.println("String & int args");
}
ThisO(){//无参构造器
this("pig",47);
System.out.println("default constructor (no args)");
}
void PrintCount() {
//this(11); 我们不能在构造器以外的方法调用构造器,哈哈
System.out.println("Count = "+Count+" String= "+s);
}
public static void main(String []args) {
ThisO t = new ThisO();
t.PrintCount();
}
}
输出:
上面的例子中,我们可以看到对于构造器的调用,只可以调用一个,而不能调用两个,并且我们也可以看出,在除构造器外,编译器禁止其他方法调用构造器。例子中以外参数和数据成员名称一致而使用了this.s = s的语法,用this.s代表数据成员,其实我们时常用到,例如void cat(int i){ this.i = i;}就可以这么初始化。
二、static
与this相对的当然就是static,static方法就是没有this的方法,在static方法内部不能调用非静态方法,反过来倒是可以的。之前我们提到一个用处就是如果不想要创建对象就调用方法的话,是要用到static的。但是我们不能出现大量的static,虽然java里面没有全局变量,但是static可以起到这个作用。(在C语言里面我们都被告知不可以使用大量的全局变量,所以java里面也是如此)。
这里就做一个关于对象初始化和清理的总结吧,对于垃圾回收机制大家可以去查看参考资料。初始化也有很多东西值得我们去关注,例如数组的初始化(java对数组的初始化避免了越界),静态类型的初始化。还有我们在c++中常常遇到的,要我们理清楚初始化的顺序(这种类型的问题常常在多态里面会提到,也是我们值得注意的)。
总结:
你会发现我在static关键字那里提到了局部和全局变量,那么它们肯定是有一定范围的,接下来我们就看看这些访问的权限范围。如有误,请指出,谢谢。