这一节我们接着上一节来继续学习this关键字.
我们之前在7.5节中的构造函数应注意的细节中提到过一个细节就是构造函数可以调用一般函数,但一般函数不能直接调用构造函数.但是我们没有深究构造函数能不能调用构造函数,那么现在我们就来看一看这个问题.
那么构造函数与构造函数之间是怎么访问呢?
为了掌握这个问题,我们必须要明确一个概念,那就是在一个类中的成员如果要被执行,就必须由对象调用.而每个对象都有一个所属的this.
java语言给了关键字this这个功能,那就是用this调用构造函数,而且也是通过参数不同选择调用不同的构造函数.
我们来看一个例子:
~~~
class Person
{
private String name;
private int age;
Person()//构造方法1
{
System.out.println("person run");
}
Person(String name)//构造方法2
{
this.name = name;
}
Person(String name,int age)//构造方法3
{
this.name = name;
this.age = age;
}
public void speak()
{
System.out.println(this.name+":"+this.age);
}
}
~~~
~~~
class ThisTest
{
public static void main(String[] args)
{
Person kobe = new Person("科比",37);
kobe.speak();
}
}
~~~
对于上面的例子我们可以看到,构造函数3中的第一句语句其实我们已经通过构造函数2实现了,那么为了提高代码的复用性,我们为什么不调用构造函数2呢,java语言中用下面的语句来调用构造函数:
~~~
Person(String name,int age)//构造方法3
{
this(name);//用this关键字调用了构造函数Person(String name)
this.age = age;
}
~~~
我们看到了this关键字可以用于在构造函数中调用其他构造函数,当然对于调用那个构造函数,还是通过参数来确定.
那么我们就明确了构造函数与构造函数之间的调用形式.
下面我们来看两个this关键字用法中需要注意的两个细节:
**第一个细节:构造函数中调用构造函数只能定义在构造函数的第一行.**
这是为什么呢,因为初始化动作一定要先执行.这就是java语言定义的一个规则,如果不是定义在第一行,编译直接通不过.
我们看例子,把上面的构造函数3的语句交换位置:
~~~
Person(String name,int age)//构造方法3
{
this.age = age;
this(name);//用this关键字调用了构造函数Person(String name)
}
~~~
我们看编译情况:
![](https://box.kancloud.cn/2016-05-18_573c41ec9f032.jpg)
我们看到编译错误:对this的调用必须是构造器中的第一个语句,这就是我们在使用this关键字时的第一个细节.
**第二个细节:注意构造函数的调用出现递归循环而导致栈内在溢出.**
我们看个例子:
~~~
Person()//构造方法1
{
this("KOBE");
System.out.println("person run");
}
Person(String name)//构造方法2
{
this();
this.name = name;
}
~~~
结果:
![](https://box.kancloud.cn/2016-05-18_573c41ecb1da1.jpg)
我们很容易发现两个构造函数相互调用,形成了递归,使得两个构造函数不断进栈,最后栈内存溢出,程序终止.
上面我们看了两个在使用this关键字时需要注意的细节,下面我们再简单的看看this关键的应用情况.
我们一般什么时候使用this呢,我们上一节中说过this的概念:this就代表对象,就是所在函数所在对象的引用.那么我们不难理解,当我们在一个类中用到了本类的对象,我们就通常会用this来引用.
那么我们来实现一个功能:判断两个人是否是同龄人.
分析一下:要判断两个人是否同龄,我们只需要比较这两个人(也就是两个Person对象)的年龄是否相等即可,那么也就是说一个对象可以直接调用Person类中的方法来与另一个对象做比较就可以了.
我们可以这样实现:
~~~
//判断两个人是否同龄
public boolean compare(Person p)
{
return this.age == p.age;
}
~~~
我们来测试一下:
~~~
class ThisTest
{
public static void main(String[] args)
{
Person kobe = new Person("科比",37);
Person james = new Person("詹姆斯",31);
kobe.speak();
james.speak();
System.out.println("这两个人相等吗:"+kobe.compare(james));
}
}
~~~
结果:
![](https://box.kancloud.cn/2016-05-18_573c41ecc70ad.jpg)
我们看到this的主要应用就是代表对象,那个对象调用了this所有的函数,我们就通俗的认为this就代表那个对象.
- 前言
- 1.1 基本常识
- 1.2 Java语言概述
- 1.3 Java语言的环境搭建
- 1.4 Java程序开发之初体验--Hello World
- 2.1 关键字
- 2.2 标识符
- 2.3 注释
- 2.4 常量
- 2.5 进制扫盲
- 2.6 变量和数据类型(1)
- 2.7 变量和数据类型(2)
- 2.8 运算符
- 3.1 if语句
- 3.2 switch语句
- 3.3 while和do-while语句
- 3.4 for语句
- 3.5 for循环的嵌套
- 3.6 break语句与continue语句
- 4.1 函数的定义
- 4.2 定义函数的两个明确
- 4.3 函数的内存加载过程
- 4.4 函数的重载
- 5.1 数组的定义
- 5.2 数组的内存分配及特点
- 5.3 数组操作中常见问题
- 5.4 数组常用操作(1)
- 5.5 数组常用操作(2)
- 5.6 二维数组
- 6.1 面向对象的概述
- 6.2 类与对象的关系
- 6.3 对象的内存体现
- 6.4 成员变量与局部变量
- 6.5 类类型参数与匿名对象
- 6.6 基本数据类型参数与引用数据类型参数的传递过程
- 6.7 封装
- 7.1 构造函数概述与默认构造函数
- 7.2 构造函数与一般函数的区别
- 7.3 构造函数的重载
- 7.4 构造函数的内存加载
- 7.5 构造函数需要注意的几个细节
- 7.6 this关键字的原理
- 7.7 this关键字的细节与应用
- 8.1 static关键字之特点
- 8.2 成员变量与静态变量的区别
- 8.3 static关键字使用的注意细节
- 8.4 main函数的解析与细节
- 8.5 static关键字的使用场景
- 8.6 静态的内存加载
- 8.7 静态代码块
- 8.8 构造代码块
- 9.1 继承
- 9.2 单继承与多重继承
- 9.3 子父类中成员变量特征体现