在java中this关键字可以完成三件事情:调用本类属性,调用本类方法,表示当前对象
1.调用本类属性
在一个类的定义的方法中可以直接访问类中的属性,但很多时候会出现方法参数名称和属性名称重复的情况,此时需要使用this.属性的形式指明要调用类中的属性而不是方法的参数
例.观察程序问题
class Book{
private String title;
private double price;
public Book(String title,double price){
title = title; //原本的目的是希望将构造方法中的title变量内容设置给title属性
price = price;
}
//setter、getter属性略
public String getInfo(){
return "书名:" + title + "; 价格:" + price;
}
}
public class TestDemo{
public static void main(String args[]){
Book book = new Book("Java开发",89.2);
System.out.println(book.getInfo());
}
}
书名:null; 价格:0.0
上述程序在Book类中直接定义一个构造方法,目的是通过构造方法为title和price两个属性进行赋值,但最终没有成功赋值,这是由于java中的变量使用具备“就近取用”的原则
在这种情况下为了可以明确的找到要访问的变量属于类中的属性,需要在变量前加上this
例.使用this关键字明确表示访问类中的属性
class Book{
private String title;
private double price;
public Book(String title,double price){
this.title = title; //原本的目的是希望将构造方法中的title变量内容设置给title属性
this.price = price;
}
//setter、getter属性略
public String getInfo(){
return "书名:" + title + "; 价格:" + price;
}
}
public class TestDemo{
public static void main(String args[]){
Book book = new Book("Java开发",89.2);
System.out.println(book.getInfo());
}
}
书名:Java开发;价格:89.2
本程序由于构造方法中访问属性时增加了this关键字,所以可以在变量名称相同的情况下,明确的区分属性或参数
2.调用本类方法
class Book{
private String title;
private double price;
public Book(String title,double price){
this.title = title; //原本的目的是希望将构造方法中的title变量内容设置给title属性
this.price = price;
}
public void print(){
System.out.println("www.yootk.com");
}
//setter、getter属性略
public String getInfo(){
this.print(); //调用本类方法
return "书名:" + title + "; 价格:" + price;
}
}
public class TestDemo{
public static void main(String args[]){
Book book = new Book("Java开发",89.2);
System.out.println(book.getInfo());
}
}
www.yootk.com
书名:Java开发; 价格:89.2
注:虽然可以直接访问本类方法,但是this.方法()是非常标准的,习惯上都会使用this调用本类属性或本类方法
例.观察程序问题
class Book{
private String title;
private double price;
public Book(){
System.out.println("一个新的Book类对象产生"); //假设这句话代表50行代码
}
public Book(String title){
System.out.println("一个新的Book类对象产生"); //假设这句话代表50行代码
this.title = title;
}
public Book(String title,double price){
System.out.println("一个新的Book类对象产生"); //假设这句话代表50行代码
this.title = title;
this.price = price;
}
//setter、getterl略
public String getInfo(){
return "书名:" + title + ";价格:" + price;
}
}
public class TestDemo{
public static void main(String args[]){
Book book = new Book("Java开发",89.2);
System.out.println(book.getInfo());
}
}
一个新的Book类对象产生
书名:Java开发;价格:89.2
对本程序的三个方法,每一个构造方法都会出现相应的信息提示,此时调用任何一个构造方法,都可以完成指定的信息输出,同时,可能会造成程序中出现大量的重复代码,此时可以用this()来完成
例.消除构造方法中的重复代码
class Book{
private String title;
private double price;
public Book(){
System.out.println("一个新的Book类对象产生"); //假设这句话代表50行代码
}
public Book(String title){
this(); //调用本类无参构造方法
this.title = title;
}
public Book(String title,double price){
this(title); //调用本类有一个参数的构造方法
this.price = price;
}
//setter、getterl略
public String getInfo(){
return "书名:" + title + ";价格:" + price;
}
}
public class TestDemo{
public static void main(String args[]){
Book book = new Book("Java开发",89.2);
System.out.println(book.getInfo());
}
}
一个新的Book类对象产生
书名:Java开发;价格:89.2
注:关于this调用构造的限制
- 使用this()调用构造方法形式的代码只能放在构造方法的首行
- 进行构造方法互相调用时,一定要保留调用的出口
对于第二个限制,观察以下代码:
class Book{
private String title;
private double price;
public Book(){
this("Hello",1.1); //调用双参构造
System.out.println("一个新的Book类对象产生"); //假设这句话代表50行代码
}
public Book(String title){
this(); //调用本类无参构造方法
this.title = title;
}
public Book(String title,double price){
this(title); //调用本类有一个参数的构造方法
this.price = price;
}
//setter、getterl略
public String getInfo(){
return "书名:" + title + ";价格:" + price;
}
}
public class TestDemo{
public static void main(String args[]){
Book book = new Book("Java开发",89.2);
System.out.println(book.getInfo());
}
}
此时的调用语句满足第一个限制,但是此时会形成一个构造方法的死循环状态,编译时会出现“构造方法递归调用”,因此,this()调用构造方法时,必须要留有出口
例.定义一个雇员类(编号、姓名、工资、部门),提供四个构造方法
- 无参构造:编号为0,姓名为无名氏,工资为0.0,部门设置为未定;
- 单参构造(传递编号):姓名为临时工,工资为800.0,部门为后勤;
- 双参构造(传递编号、姓名):工资为2000.0,部门为技术部门;
- 四参构造
方法一:按照传统的风格实现
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 = 800.0;
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;
}
//setter、getter略
}
public class TestDemo{
public static void main(String args[]){
Emp ea = new Emp();
Emp eb = new Emp(7396);
Emp ec = new Emp(7566,"ALLEN");
Emp ed = new Emp(7839,"KING",5000.0,"财务部");
System.out.println(ea.getInfo());
System.out.println(eb.getInfo());
System.out.println(ec.getInfo());
System.out.println(ed.getInfo());
}
}
雇员编号:0. 姓名:无名氏. 工资:0.0. 部门:未定
雇员编号:7396. 姓名:临时工. 工资:800.0. 部门:后勤部
雇员编号:7566. 姓名:ALLEN. 工资:2000.0. 部门:技术部
雇员编号:7839. 姓名:KING. 工资:5000.0. 部门:财务部
本程序可以满足开发的要求,但是可以发现程序中存在重复的代码
方法二:利用构造方法互相调用简化代码
class Emp{
private int empno;
private String ename;
private double sal;
private String dept;
public Emp(){
this(0,"无名氏",0.0,"未定"); //调用四参构造
}
public Emp(int empno){ //单参构造
this(empno,"临时工",800.0,"后勤"); //调用四参构造
}
public Emp(int empno,String ename){
this(empno,ename,2000.0,"技术部"); //调用四参构造
}
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;
}
//setter、getter略
}
public class TestDemo{
public static void main(String args[]){
Emp ea = new Emp();
Emp eb = new Emp(7396);
Emp ec = new Emp(7566,"ALLEN");
Emp ed = new Emp(7839,"KING",5000.0,"财务部");
System.out.println(ea.getInfo());
System.out.println(eb.getInfo());
System.out.println(ec.getInfo());
System.out.println(ed.getInfo());
}
}
利用this()语法的形式,很好的解决了构造方法中代码重复的问题
3.表示当前对象
注:this关键字在应用的过程中最重要的概念:当前对象,而所谓的当前对象指的就是当前正在调用类中方法的实例化对象
例.直接输出对象
class Book{
public void print(){ //调用print()方法的对象就是当前对象,this则自动与此对象指向同一块内存地址
System.out.println("this = " + this); //this就是当前调用方法的对象
}
}
public class TestDemo{
public static void main(String args[]){
Book booka = new Book(); //实例化新的Book类对象
booka.print(); //调用Book类的print()方法输出,此时booka为当前对象
System.out.println("-------------------------");
Book bookb = new Book(); //实例化新的Book类对象
System.out.println("bookb = " + bookb); //主方法中输出Book类对象
bookb.print(); //调用Book类的print()方法输出,此时bookb为当前对象
}
}
this = Book@762efe5d
-------------------------
bookb = Book@71dac704
this = Book@71dac704
本例首先实例化了两个Book类对象,然后在主方法中直接进行对象信息的输出。结果可见,每个对象都有一个独立的对象编码,在使用不同的额对象调用print()方法时,this的引用同样会发生变化,即this为当前对象