李兴华Java8笔记13:this关键字详解

this有一个核心概念:指的是当前对象。Java里面可以实现对类属性的调用、类方法的调用、表示当前对象。接下来一一介绍:

1.调用属性

首先看一个之前写过的很简单的代码:

class Book{
	private String title;
	private Double price;

	public Book(String t, Double p){
		title = t;
		price = p;
	}

	public void getInfo(){
		System.out.println("书名:"+title+",价格:"+price);
	}
}
public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java开发",89.2);
		books.getInfo(); //输出:书名:Java开发,价格:89.2
	}
} 

在构造方法中,我们设置书名和价格的参数设置为了t、p。但是这种命名方法并不符合规范,我们想将形参设置为title、price,于是有了下面的改进:

class Book{
	private String title;
	private Double price;

	public Book(String title, Double price){
		title = t;
		price = p;
	}

	public void getInfo(){
		System.out.println("书名:"+title+",价格:"+price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java开发",89.2);
		books.getInfo();// 输出:书名:null,价格:null
	}
} 

但是编译运行之后,我们什么也没有得到。这是因为变量有一个作用域的概念,上面的Book构造方法中有一个title、Book 类中同样也有一个成员属性title,但是构造方法中的title的优先级比较高。因此当我们用title = title 的时候,前面的title并不是类中的属性title,那怎样才能够在保证参数名和类属性名一致的情况下,正确的调用到成员属性并赋值呢?那就是this关键字了!:

class Book{
	private String title;
	private Double price;

	public Book(String title, Double price){
		this.title = title;
		this.price = price;
	}

	public void getInfo(){
		System.out.println("书名:"+this.title+",价格:"+this.price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java开发",89.2);
		books.getInfo(); //输出:书名:Java开发,价格:89.2
	}
} 

this关键字所指向的title就是本类中的成员属性,因此在以后的开发中,只要是在类中使用成员属性,我们就用this关键字来调用。

2. 调用方法

2.1 调用构造方法

类中的多个构造方法可能存在相互调用的情况。使用的形式就是this(参数,参数)。例子如下,先要求没生成一个对象,无论是调用的无参构造还是若干参数的构造方法,都要求输出一个提示语句:新的对象产生。没用this()的时候我们可以这样来写:

class Book{
	private String title;
	private Double price;

	// 无参构造方法
	public Book(){
		System.out.println("新的对象产生");
	}

	// 一个参数的构造方法
	public Book(String title){
		System.out.println("新的对象产生");
		this.title = title; 
	}

	// 两个参数的构造方法
	public Book(String title, Double price){
		System.out.println("新的对象产生");
		this.title = title;
		this.price = price;
	}

	public void getInfo(){
		System.out.println("书名:"+this.title+",价格:"+this.price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java开发",89.2); //输出:新的对象产生
		books.getInfo(); 
		//输出:书名:Java开发,价格:89.2
	}
}

但是这些写会产生很多的重复代码,比如System.out.println(“新的对象产生”)、this.title = title;都属于重复代码。但是有了this关键字就不一样了,我们可以用this()代表调用无参构造方法,用this(参数)表示调用一个参数的构造方法,一次类推。于是功能相同的改进代码如下:

class Book{
	private String title;
	private Double price;

	// 无参构造方法
	public Book(){
		System.out.println("新的对象产生");
	}

	// 一个参数的构造方法
	public Book(String title){
		this();
		this.title = title; 
	}

	// 两个参数的构造方法
	public Book(String title, Double price){
		this(title);
		this.price = price;
	}

	public void getInfo(){
		System.out.println("书名:"+this.title+",价格:"+this.price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java开发",89.2); //输出:新的对象产生
		books.getInfo(); 
		//输出:书名:Java开发,价格:89.2
	}
}

这样一来,多个构造方法之间相互调用的重复代码问题是解决了,但是新的问题油然而生

  • Java规定this(参数)只能放在方法中的第一行,换个位置就会发生错误。
  • 构造方法能调用普通方法,但是普通方法无法使用this()调用构造方法。
  • 构造方法相互调用的时候一定要保留调用的出口。

在上面的代码中,两参构造方法调用了一参构造方法,一参构造方法调用了无参构造方法,无参构造方法停止了调用。这让程序有了一个出口,得以让代码正常运行。如果我们在无参构造中再次调用两参构造方法,会出现“构造方法递归调用”的错误提示。

// 无参构造方法
	public Book(){
        this("Hello",123.0);
		System.out.println("新的对象产生");
	}

	// 一个参数的构造方法
	public Book(String title){
		this();
		this.title = title; 
	}

	// 两个参数的构造方法
	public Book(String title, Double price){
		this(title);
		this.price = price;
	}


2.2 实例联系

定义一个雇员类(员工编号,姓名,工资,部门),在这个类中编写四个构造方法:

  • 无参构造:编号为:0、姓名为:“无名氏”、工资为:0.0、部门设置:“未定”
  • 单参构造(传递编号):姓名为:“临时工”、工资为:800.0、部门设置:“后勤部”
  • 双参构造(传递编号、姓名):工资为:2000.0、部门设置:“技术部”
  • 四参构造(传递编号、姓名、工资、部门)

实现方法一:普通方法:要啥给啥!

class Emp{
	private int number;
	private String name;
	private Double salary;
	private String department;

	// 无参构造
	public Emp(){
		this.number = 0;
		this.name = "无名氏";
		this.salary = 0.0;
		this.department = "未定";
	}

	// 单参构造
	public Emp(int number){
		this.number = number;
		this.name = "临时工";
		this.salary = 800.0;
		this.department = "后勤部";
	}

	// 双参构造
	public Emp(int number, String name){
		this.number = number;
		this.name = name;
		this.salary = 2000.0;
		this.department = "技术部";
	}

	// 四参构造
	public Emp(int number, String name, Double salary, String department){
		this.number = number;
		this.name = name;
		this.salary = salary;
		this.department = department;
	}

	public String getInfo(){
		return "编号:"+this.number+",姓名:"+this.name+",工资"+this.salary+",部门:"+this.department;
	}
}

public class Hello{
	public static void main(String[] args){
		Emp emp1 = new Emp(); 
		Emp emp2 = new Emp(1234); 
		Emp emp3 = new Emp(3389,"向东"); 
		Emp emp4 = new Emp(2232,"金津",123.0,"销售部"); 
		
		System.out.println(emp1.getInfo());
		System.out.println(emp2.getInfo());
		System.out.println(emp3.getInfo());
		System.out.println(emp4.getInfo());
	}
}

// 输出结果
编号:0,姓名:无名氏,工资0.0,部门:未定
编号:1234,姓名:临时工,工资800.0,部门:后勤部
编号:3389,姓名:向东,工资2000.0,部门:技术部
编号:2232,姓名:金津,工资123.0,部门:销售部

上面方法的缺点显而易见,代码重复率太高,我们可以用this()方法进行改进:

class Emp{
	private int number;
	private String name;
	private Double salary;
	private String department;

	// 无参构造
	public Emp(){
		this(0,"无名氏",0.0,"未定");
	}

	// 单参构造
	public Emp(int number){
		this(number,"临时工",800.0,"后勤部");
	}

	// 双参构造
	public Emp(int number, String name){
		this(number,name,2000.0,"技术部");
	}

	// 四参构造
	public Emp(int number, String name, Double salary, String department){
		this.number = number;
		this.name = name;
		this.salary = salary;
		this.department = department;
	}

	public String getInfo(){
		return "编号:"+this.number+",姓名:"+this.name+",工资"+this.salary+",部门:"+this.department;
	}
}

public class Hello{
	public static void main(String[] args){
		Emp emp1 = new Emp(); 
		Emp emp2 = new Emp(1234); 
		Emp emp3 = new Emp(3389,"向东"); 
		Emp emp4 = new Emp(2232,"金津",123.0,"销售部"); 
		
		System.out.println(emp1.getInfo());
		System.out.println(emp2.getInfo());
		System.out.println(emp3.getInfo());
		System.out.println(emp4.getInfo());
	}
}

2.3 调用普通方法

普通方法之间的调用可以不加this,但是为了保证程序的严谨性,还是建议加上this.

3. 表示当前对象

this表示当前对象,表示正在调用当前方法的对象。

class Book{
	public Book(){
		System.out.println("this:"+this);
	}
}

public class Hello{
	public static void main(String[] args){
		Book book = new Book(); 	// 输出当前对象的堆内存地址
		System.out.println(book);	// 也是输出地址与上面的地址是一样的
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值