您的位置:首页 > 编程语言 > Java开发

Java基础: 关键字 this

2011-05-25 15:13 295 查看
在正式进入主题之前,先来点“热身”操作-成员变量的初始化!

举一个例子,如下所示:

public class Animal {
int weight = 10;
String gender = "male";

/**
* constructor 1
*/
public Animal() {
// 初始化成员变量
this.weight = 12;
this.gender = "female";
System.out.println("---无参数的构造方法---");
}

/**
* constructor 2
*/
public Animal(int weight) {
System.out.println("---带参数weight的构造方法---");
}
}
 

在这里,声明成员变量时我没有采用默认初始化,而是手动赋值:

int weight = 10;
String gender = "male";
 

在constructor 1中我又初始化了成员变量。并且使用了this,不过在这里用与不用this没有影响!!

做一个简单测试,如下:

class TestAnimal {
public static void main(String[] args) {
/*Animal animal = new Animal();
animal = new Animal(100);
animal = new Animal("male");
animal = new Animal(200, "female");*/
Animal animal = new Animal(90);
System.out.println("animal.gender: " + animal.gender);
System.out.println("animal.weight: " + animal.weight);
}
}
 

采用constructor 2创建Animal对象,而不是采用constructor 1来创建Animal对象。

打印结果:

---带参数weight的构造方法---
animal.gender: male
animal.weight: 10
 

可见,打印的是声明成员变量时的值,不是constructor 1中初始化的值。

当然,你会说如果我采用constructor 1方法创建Animal对象,那么结果肯定是:

---无参数的构造方法---
animal.gender: female
animal.weight: 12
 

对,您说的很对!在这里,只是想说明构造方法初始化成员变量之前,其实成员变量已经悄悄的初始化一次啦!

好了,回归正题吧??!

 

1. this与构造方法

 

this 可以用于区别同名的变量,也可以调用构造方法,看一个小示例:

package mark.csdn;
public class Animal {
int weight = 10;
String gender = "male";

/**
* constructor 1
*/
public Animal() {
// 初始化成员变量
this.weight = 12;
this.gender = "female";
System.out.println("---无参数的构造方法---");
}

/**
* constructor 2
*/
public Animal(int weight) {
this();// constructor 1
this.weight = weight;
System.out.println("---带参数weight的构造方法---");
}

/**
* constructor 3
*/
public Animal(int weight, String gender) {
this(weight);// constructor 2
this.gender = gender;
System.out.println("---带参数weight、gender的构造方法---");
}

/**
* constructor 4
*/
public Animal(String gender) {
this(20, gender);// 调用constructor 3
System.out.println("---带参数gender的构造方法---");
}
}
 

测试代码:

class TestAnimal {
public static void main(String[] args) {
Animal animal = new Animal();
animal = new Animal(100);
animal = new Animal("male");
animal = new Animal(200, "female");
}
}
 

小结如下:

<1> this,只能在方法内部使用

<2> this() 或者 this(***) 形式调用构造方法,注意:

        <a> 只可以放在构造方法的第一句

        <b> 只可以调用本类的构造方法,不可以调用父类的,调用父类用关键字 super

 

2. this 不是 static

 

<1> this 是一个变量,并且是一个局部变量,它代表当前对象句柄。

<2> 类的每个方法前面默认有个 this

<3> this不 可以用于静态方法中,说明 this 不是 static 类型变量。但是 this 可以引用静态成员

示例代码:

package mark.csdn;
public class Father {
String str = "Hello,I'm father!";
static int x;

public void getName() {
System.out.println(str);
System.out.println("father: " + str);
// 调用静态方法
this.set();
}

public void get() {
this.getName();
// 调用静态成员变量
this.x=0;
}

public static void set() {
// this.get(); // 错误
}
}
 

从上面代码中,可以看出 this 既可以调用 static 方法或者变量,也可以调用非 static 方法和变量。

但是在static 方法中不可以调用 this 变量,回忆一下,static 方法中不可以调用非 static 方法,所以 this 是非 static 的变量。

再来看一个小示例,该类继承 Father,重写 getName() 方法,在打印之前,可以试想一下结果是什么??

class Child extends Father {

@Override
public void getName() {
str = "Hello,I'm child!";
System.out.println("child: " + str);
}
public static void main(String[] args) {
new Child().get();
}
}
 

new Child()调用继承父类的get()方法,看看父类get()方法:

public void get() {
this.getName();
// 调用静态成员变量
this.x=0;
}
 

使用了this来调用getName()方法,原来以为打印结果会是跟父类有关,但是出人意料的结果显示如下:

child: Hello,I'm child!
 

仔细分析一下,您就会明白这是为什么。

首先,每个类都会有一个this变量,当你调用get()方法虽然是调用了父类的方法,而且父类中该方法使用this调用了自身的getName()方法,但是在类Child中,this指向了当前Child对象。所以结果是上面那样。

其次,也许这种解释会好理解一点吧,父类get()方法等效与下面写法:

public void get() {
getName();
// 调用静态成员变量
this.x=0;
}
 

 

这下,可以很清晰的看出打印结果的来由啦!!

 

3. this与内部类

这里所说的内部类指的是非static内部类,直接看代码吧!假设你已经明白下面两点的话:

<1> 内部类可以访问外部类的任何权限的成员变量、常量或者成员方法

<2> 外部类不可以访问内部类的任何权限的成员变量或者成员方法

 

package mark.csdn;
public class Outer {
int x = 100 ;
/**
* 私有方法,可以被内部类访问
*/
private void get() {
System.out.println("I'm get(),Outer's member method!");
}

class Inner {
int x = 10;

/**
* 内部类的方法,与外部类的get方法同名
* 注意:调用同名方法的技巧
*/
public void get() {
System.out.println("I'm get(),Inner's member method!");
// 调用外部类的get方法
Outer.this.get();
}

/**
* 注意:调用同名变量的技巧
*/
public void getInfo() {
int x = 1;// 临时变量
System.out.println("Inner's temp parameter x = " + x);
// 内部类成员变量
System.out.println("Inner's member parameter x = " + this.x);
// 外部类成员变量
System.out.println("Outer's member parameter x = " + Outer.this.x);
}
}
}
 

代码很简单,就是一个外部类和一个内部类的嵌套,使用this区别同名变量或者同名方法。

测试代码如下:

 
class Test {
public static void main(String[] args) {
// 创建外部类对象
Outer out = new Outer();
// 创建内部类对象
Outer.Inner inner = out.new Inner();
inner.getInfo();
inner.get();
}
}
 

打印结果:

Inner's temp parameter x = 1
Inner's member parameter x = 10
Outer's member parameter x = 100
I'm get(),Inner's member method!
I'm get(),Outer's member method!
 

4. 返回当前对象

主要参考 tij 中的代码。将句柄返回给当前对象,那么经常在return 语句中使用 this。

class Leaf {
private int i = 0;
Leaf increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
public static void main(String[] args) {
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
}
 

在 Java 源码中,有很多类似用法,看看a ppend 方法源码:

public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);
str.getChars(0, len, value, count);
count = newCount;
return this;
}
 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: