具体内容
在 Java 程序中,当局部变量
和全局变量
数据类型和名称都相同的时,此时全局变量会被隐藏而变得不能使用。即:局部变量会覆盖掉全局变量
。
在 Java 程序中,利用 this 关键字可以显示类属性的调用、类方法的调用、表示当前对象。
使用 this 的语法格式如下:
this.成员变量名
this.成员方法名()
this 具体使用
调用成员变量
Demo.java
// 定义一个内部类 BookInfo
class BookInfo {
// 内部类的属性
String title;
double price;
// 内部类的方法
public void getInfo() {
// 打印的结果是当前对象的属性,是当前对象
System.out.println("图书名称:" + this.title + ",价格为:" + this.price);
}
}
public class Demo {
public static void main(String[] args) {
// 实例化 两个BookInfo 的对象
BookInfo bookA = new BookInfo();
BookInfo bookB = new BookInfo();
// 给 bookA 增加属性
bookA.price = 89.8;
bookA.title = "Java 开发"; // 给 booA 这个对象赋值,
// 给 bookB 增加属性
bookB.price = 69.8;
bookB.title = "JSP 开发"; // 给 booB 这个对象赋值
// 分别调用 getInfo() 方法
bookA.getInfo();
bookB.getInfo();
}
}
控制台输出
图书名称:Java 开发,价格为:89.8
图书名称:JSP 开发,价格为:69.8
说明
通过控制台的输出,可以看到程序上面实例化的两个对象:bookA、bookB,分别通过 getInfo() 打印出来的数据都是自己的,即在调用 BookInfo 中的 getInfo()
时,调用时候的 this 就是执行当时的调用对象
。例如:当 bookA 调用 getInfo() 时,当前的 this 就是指的是 bookA。
成员变量的作用域
Demo.java
class BookInfo {
String title;
double price;
public void getInfo() {
String title = "我是默认值"; // 局部变量
// 输出的结果也为局部变量
System.out.println("title 值为:"+ title);
// 输出的结果为全局变量
System.out.println("图书名称:" + this.title + ",价格为:" + this.price);
}
}
public class Demo {
public static void main(String[] args) {
// 实例化 BookInfo 对象
BookInfo bookA = new BookInfo();
// 给 bookA 增加属性
bookA.price = 89.8;
bookA.title = "Java 开发";
bookA.getInfo();
}
}
控制台输出
title 值为:我是默认值
图书名称:Java 开发,价格为:89.8
说明
如果我们在 BookInfo 类中的 getInfo() 方法中,全部都是使用 title
,而不是使用 this.title
,那么输出的结果就全部为 我是默认值
。 那是因为我们的定义了局部变量,如果没有 this 关键字去声明,那么所有的 title 引入的指向都是 当前的局部变量。在上面的程序代码中就是:我是默认值。
反过来看,当我们加上了 this 关键字,就是表示当前的对象,而 this.title 就是指的是我们定义的全局的属性了。
调用成员方法
使用传统的方式
在使用 this 关键字之前,我们先看下传统的方法。在下面的代码中有四个构造器方法。分别使用这四个构造器方法去创建对象。并且输出结果。
TestDemo.java
class Emp{
private int empno;
private String ename;
private double sal;
private String dept;
public Emp() {
this.empno = 0;
this.ename = "无名氏";
this.sal = 0.0;
this.dept = "无";
}
public Emp(int empno){
this.empno = empno;
this.ename = "临时工";
this.sal = 200;
this.dept = "测试组";
}
public Emp(int empno, String ename){
this.empno = empno;
this.ename = ename;
this.sal = 2000.0;
this.dept = "技术部";
}
public Emp(int empno, String ename, double sal, String dept){
this.empno = empno;
this.ename = ename;
this.sal = sal;
this.dept = dept;
}
public String getInfo() {
return "雇员编号:" + this.empno + ", 雇员名称" + this.ename + ", 工资" + this.sal + ",部门"+ this.dept;
}
}
public class TestDemo {
public static void main(String[] args) {
Emp emp1 = new Emp();
Emp emp2 = new Emp(2);
Emp emp3 = new Emp(3, "张三");
Emp emp4 = new Emp(4, "张三", 5000, "经理部");
System.out.println(emp1.getInfo());
System.out.println(emp2.getInfo());
System.out.println(emp3.getInfo());
System.out.println(emp4.getInfo());
}
}
控制台输出
雇员编号:0, 雇员名称无名氏, 工资0.0,部门无
雇员编号:2, 雇员名称临时工, 工资200.0,部门测试组
雇员编号:3, 雇员名称张三, 工资2000.0,部门技术部
雇员编号:4, 雇员名称张三, 工资5000.0,部门经理部
使用 this 调用方法
接下来,我们使用 this 来改写,上面的写法肯定不是最优的方案。因为存在好多的重复性的代码。然后我们使用 this 来重构。但是在下面的代码中,需要留有一个 this 出口。
++出口是指的是:我们在创建构造器的时候,不能每一个 构造器方法中都使用 this() 方法,因为如果全部都使用,程序执行的就会陷入“递归调用” 就会报错。++
在下面的代码中,我们需要了解的知识是:this() 就是指我们当前的调用的构造器方法。
TestDemo.java
package com.wq.study.reference;
class Emp{
private int empno;
private String ename;
private double sal;
private String dept;
public Emp() {
// 我们通过使用 this() 方法来调用我们的 四参构造方法
this(0, "无名氏", 0.0, "无"); // 当前一行就可以替换下面的四行代码
/*由于改写,这段代码就注释掉
this.empno = 0;
this.ename = "无名氏";
this.sal = 0.0;
this.dept = "无";*/
}
public Emp(int empno){
this(empno, "临时工", 200, "测试"); // 在这个地方我们也使用 this() 方法来改写
/* 由于改写,这段代码就注释掉
this.empno = empno;
this.ename = "临时工";
this.sal = 200;
this.dept = "测试组";*/
}
public Emp(int empno, String ename){
this(empno, ename, 2000, "技术部"); // 同样我们使用 this() 方法来改写
/* 由于改写,这段代码就注释掉
this.empno = empno;
this.ename = ename;
this.sal = 2000.0;
this.dept = "技术部";*/
}
public Emp(int empno, String ename, double sal, String dept){
// 我们这个地方留有出口。就不会导致产生递归调用而报错
this.empno = empno;
this.ename = ename;
this.sal = sal;
this.dept = dept;
}
public String getInfo() {
return "雇员编号:" + this.empno + ", 雇员名称" + this.ename + ", 工资" + this.sal + ",部门"+ this.dept;
}
}
public class TestDemo {
public static void main(String[] args) {
Emp emp1 = new Emp();
Emp emp2 = new Emp(2);
Emp emp3 = new Emp(3, "张三");
Emp emp4 = new Emp(4, "张三", 5000, "经理部");
System.out.println(emp1.getInfo());
System.out.println(emp2.getInfo());
System.out.println(emp3.getInfo());
System.out.println(emp4.getInfo());
}
}
控制台输出
雇员编号:0, 雇员名称无名氏, 工资0.0,部门无
雇员编号:2, 雇员名称临时工, 工资200.0,部门测试
雇员编号:3, 雇员名称张三, 工资2000.0,部门技术部
雇员编号:4, 雇员名称张三, 工资5000.0,部门经理部
说明
从控制台的输出可以看出,这个两个结果是没有区别的,即说明我们改写成功,但是需要有一点说明就是一定要在某一个 构造方法中留有出口。
this 表示当前对象
this 表示当前的对象,其实还是比较好理解。我们通过以下代码来了解。
Demo.java
class BookInfo {
public void getInfo() {
System.out.println("this ="+ this);
}
}
public class Demo {
public static void main(String[] args) {
BookInfo bookA = new BookInfo();
System.out.println("bookA:"+bookA);
bookA.getInfo();
System.out.println("--------------------");
BookInfo bookB = new BookInfo();
System.out.println("bookB:"+bookB);
bookB.getInfo();
}
}
控制台
bookA: BookInfo@7852e922
this = BookInfo@7852e922
--------------------
bookB: BookInfo@4e25154f
this = BookInfo@4e25154f
说明
我们打印出来的消息可以看到,this 就是当前的对象地址,指的是当前的调用的对象。
通过复杂的代码理解 this
对于 this 的理解,我们可以通过下面的复杂点的代码来理解。代码上面有详细的注释。大家仔细看就好了。
class A{
private B b; // 将 B 作为私有的成员变量
public A() {
this.b = new B(this); // 2.实例化对象b,将当前的this(指的是 A)传递到B的构造器中, 并且将实例化出来的 B对象 给到 A 对象中的 B(为 A 对象中的私有成员变量)
this.b.get(); // 4.通过 b 调用 get() 方法
}
public void print() {
System.out.println("Hello word!"); // 6.打印输出 Hello word!
}
}
class B{
private A a; // 将 A 作为私有的成员变量
public B(A a) {
this.a = a; // 3.将传递过来的 A 赋值给 自己的私有变量 A,由于作用域的关系,this指向的是 B
}
public void get() {
this.a.print(); // 5.通过这个地方调用 A的 print()
}
}
public class Demo {
public static void main(String[] args) {
A temp = new A(); // 1.实例化对象 A
}
}
总结
- 类中的属性调用以后都要加上
this
- 类中的构造方法间的互相调用,一定要保留有出口(即存在有一个构造方法没有使用 this() )
-
this
表示当前对象,指的是当前正在调用类中的方法的对象,this
不是一个固定的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。