Java学习笔记(18)--关键字this详解
2017-09-25 17:35
411 查看
在整个Java中,只要是代码开发,几乎都离不开this。在Java中this可以完成三件事情:表示本类属性、表示本类方法、当前对象。
一、“this.属性”表示本类属性
讲解之前,我们先看一段代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
运行结果:
我们来观察一下构造方法:
2
3
4
这个时候的构造方法的两个参数的目的是为类中的name和age两个属性初始化,可是这个方法上的两个参数,一个是字母n,另外一个是字母a,什么意思?那么最好的做法,既然构造方法的两个参数是为了name和age属性初始化使用的,最好将其的名称也定义为name和age才最为合适:
2
3
4
此时构造方法上的两个参数的名称变得有意义了。但是这样一来,一个问题就出现了,发现属性没有内容了。因为在程序之中是以“{}”作为一个分界,采用就近的取用原则,所以现在为了可以明确的指定要操作的是类中属性的话,那么应该采用“this.属性”的形式完成,代码应该变为:
2
3
4
一个开发建议:
只要是调用本类中的属性,都使用“this.属性”的方式来进行。
二、this调用本类方法
一个类中的方法分为两种:
(1)普通方法:如果现在要调用的是本类方法,可以使用“this.方法()”调用;
(2)构造方法:调用构造方法使用“this(参数…)”调用。
例如:现在一个类之中存在了三个构造方法(无参、有一个参数、有两个参数),但是不管使用何种构造方法,都要求在实例化对象产生的时候输出一行提示信息:“一个新的类对象被实例化”。按照之前的学习,代码编写如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
运行结果:
2
不过,遗憾的是,此时的程序之中出现了大量的重复代码,而我们的目标是尽量没有重复。这种情况下就可以利用this()来完成:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
运行结果:
2
以上就使用this()就完成了构造方法之间的互相调用操作。
但是要注意的是:所有的构造方法是在对象实例化的时候被默认调用,而且是在调用普通方法之前调用,所以使用“this()”调用构造方法的操作,一定要放在构造方法的首行;
2
3
4
另外,我们来看一段代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
运行结果:
2
3
4
5
6
7
8
通过以上代码和运行结果不难看出:递归调用了构造器。
所以,如果一个类之中存在了多个构造方法的话,并且这些构造方法都使用了this()互相调用,那么至少要保留一个构造方法没有调用其他构造,以作为程序的出口。
我们来看一个构造方法互相操作的实例:
定义一个雇员类(员工号、姓名、薪水、部门),在这个类中提供四个工作方法:
A、单参,只传递员工号,则员工姓名:无名氏,薪水:0,部门:未定
B、双参,传递员工号,姓名,则员工薪水为1000,部门:后勤
C、四参,传递员工号,姓名,部门,薪水
D、无参,则均为空值
来看代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
运行结果:
2
3
4
如果按照以上的方式开发,是可以完成功能的实现,但是代码中却存在了重复的代码,很明显,这样不合适。于是,我们通过构造方法的相互调用来对构造方法进行如下改动:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行结果如下:
2
3
4
这种构造方法的互相调用是在对象实例化的时候,不同的构造有一些相同操作的情况下去使用。
三、this表示当前对象
当前对象,是指当前正在调用类中方法的对象。
先来看一段代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行结果:
2
在Book类中加上一个打印this的方法:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
运行结果:
2
3
4
5
那么,之前的“this.属性”实际上就是当前对象的属性,一定是堆内存中保存的内容。
一、“this.属性”表示本类属性
讲解之前,我们先看一段代码:
package com.wz.thisdemo; class Person { private String name ; private int age ; public Person(String n,int a) { name = n ; age = a ; } // setter、getter略 public String getInfo() { return "姓名:" + name + ",年龄:" + age ; } } public class TestDemo { public static void main(String args[]) { Person per = new Person("张三",20) ; System.out.println(per.getInfo()) ; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
运行结果:
姓名:张三,年龄:201
我们来观察一下构造方法:
public Person(String n,int a) { name = n ; age = a ; }1
2
3
4
这个时候的构造方法的两个参数的目的是为类中的name和age两个属性初始化,可是这个方法上的两个参数,一个是字母n,另外一个是字母a,什么意思?那么最好的做法,既然构造方法的两个参数是为了name和age属性初始化使用的,最好将其的名称也定义为name和age才最为合适:
public Person(String name,int age) { name = name ; age = age ; }1
2
3
4
此时构造方法上的两个参数的名称变得有意义了。但是这样一来,一个问题就出现了,发现属性没有内容了。因为在程序之中是以“{}”作为一个分界,采用就近的取用原则,所以现在为了可以明确的指定要操作的是类中属性的话,那么应该采用“this.属性”的形式完成,代码应该变为:
public Person(String name,int age) { this.name = name ; this.age = age ; }1
2
3
4
一个开发建议:
只要是调用本类中的属性,都使用“this.属性”的方式来进行。
二、this调用本类方法
一个类中的方法分为两种:
(1)普通方法:如果现在要调用的是本类方法,可以使用“this.方法()”调用;
(2)构造方法:调用构造方法使用“this(参数…)”调用。
例如:现在一个类之中存在了三个构造方法(无参、有一个参数、有两个参数),但是不管使用何种构造方法,都要求在实例化对象产生的时候输出一行提示信息:“一个新的类对象被实例化”。按照之前的学习,代码编写如下:
package com.wz.thisdemo; class Person { private String name ; private int age ; public Person() { System.out.println("*** 一个新的Person类对象被实例化。") ; } public Person(String name) { System.out.println("*** 一个新的Person类对象被实例化。") ; this.name = name ; } public Person(String name,int age) { System.out.println("*** 一个新的Person类对象被实例化。") ; this.name = name ; this.age = age ; } // setter、getter略 public String getInfo() { return "姓名:" + this.name + ",年龄:" + this.age ; } } public class TestDemo { public static void main(String args[]) { Person per = new Person("张三",20) ; System.out.println(per.getInfo()) ; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
运行结果:
*** 一个新的Person类对象被实例化。 姓名:张三,年龄:201
2
不过,遗憾的是,此时的程序之中出现了大量的重复代码,而我们的目标是尽量没有重复。这种情况下就可以利用this()来完成:
package com.wz.thisdemo; class Person { private String name ; private int age ; public Person() { System.out.println("*** 一个新的Person类对象被实例化。") ; } public Person(String name) { this() ; // 调用无参构造 this.name = name ; } public Person(String name,int age) { this(name) ; // 调用有一个参数的构造 this.age = age ; } // setter、getter略 public String getInfo() { return "姓名:" + this.name + ",年龄:" + this.age ; } } public class TestDemo { public static void main(String args[]) { Person per = new Person("张三",20) ; System.out.println(per.getInfo()) ; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
运行结果:
*** 一个新的Person类对象被实例化。 姓名:张三,年龄:201
2
以上就使用this()就完成了构造方法之间的互相调用操作。
但是要注意的是:所有的构造方法是在对象实例化的时候被默认调用,而且是在调用普通方法之前调用,所以使用“this()”调用构造方法的操作,一定要放在构造方法的首行;
public Person(String name) { this() ; // 调用无参构造,放在首行 this.name = name ; }1
2
3
4
另外,我们来看一段代码:
package com.wz.thisdemo; class Person { private String name ; private int age ; public Person() { this("",10) ; // 调用两个参数的构造 System.out.println("*** 一个新的Person类对象被实例化。") ; } public Person(String name) { this() ; // 调用一个参数的构造 this.name = name ; } public Person(String name,int age) { this(name) ; // 调用有一个参数的构造 this.age = age ; } // setter、getter略 public String getInfo() { return "姓名:" + this.name + ",年龄:" + this.age ; } } public class TestDemo { public static void main(String args[]) { Person per = new Person("张三",20) ; System.out.println(per.getInfo()) ; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
运行结果:
Exception in thread "main" java.lang.Error: Unresolved compilation problems: Recursive constructor invocation Person(String, int) Recursive constructor invocation Person() Recursive constructor invocation Person(String) at com.wz.thisdemo.Person.<init>(TestDemo.java:6) at com.wz.thisdemo.TestDemo.main(TestDemo.java:23)1
2
3
4
5
6
7
8
通过以上代码和运行结果不难看出:递归调用了构造器。
所以,如果一个类之中存在了多个构造方法的话,并且这些构造方法都使用了this()互相调用,那么至少要保留一个构造方法没有调用其他构造,以作为程序的出口。
我们来看一个构造方法互相操作的实例:
定义一个雇员类(员工号、姓名、薪水、部门),在这个类中提供四个工作方法:
A、单参,只传递员工号,则员工姓名:无名氏,薪水:0,部门:未定
B、双参,传递员工号,姓名,则员工薪水为1000,部门:后勤
C、四参,传递员工号,姓名,部门,薪水
D、无参,则均为空值
来看代码:
package com.wz.thisdemo; class Emp { private int empno ; private String ename ; private double salary ; private String dept ; public Emp(){} public Emp(int empno){ this.empno = empno ; this.ename = "无名氏" ; this.salary = 0.0 ; this.dept = "未定" ; } public Emp(int empno,String ename){ this.empno = empno ; this.ename = ename ; this.salary = 1000.0 ; this.dept = "后勤" ; } public Emp(int empno,String ename,double salary,String dept){ this.empno = empno ; this.ename = ename ; this.salary = salary ; this.dept = dept ; } public String getInfo() { return "雇员编号:" + this.empno + ",姓名:" + this.ename + ",工资:" + this.salary + ",部门:" + this.dept ; } } public class TestDemo { public static void main(String args[]) { Emp emp1 = new Emp(); System.out.println(emp1.getInfo()); Emp emp2 = new Emp(4555); System.out.println(emp2.getInfo()); Emp emp3 = new Emp(6542,"小王"); System.out.println(emp3.getInfo()); Emp emp4 = new Emp(4578,"小明",12000,"技术部"); System.out.println(emp4.getInfo()); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
运行结果:
雇员编号:0,姓名:null,工资:0.0,部门:null 雇员编号:4555,姓名:无名氏,工资:0.0,部门:未定 雇员编号:6542,姓名:小王,工资:1000.0,部门:后勤 雇员编号:4578,姓名:小明,工资:12000.0,部门:技术部1
2
3
4
如果按照以上的方式开发,是可以完成功能的实现,但是代码中却存在了重复的代码,很明显,这样不合适。于是,我们通过构造方法的相互调用来对构造方法进行如下改动:
public Emp(){} public Emp(int empno){ this(empno,"无名氏",0.0,"未定") ;//调用四参构造方法 } public Emp(int empno,String ename){ this(empno,ename,1000.0,"后勤") ;//调用四参构造方法 } public Emp(int empno,String ename,double salary,String dept){ this.empno = empno ; this.ename = ename ; this.salary = salary ; this.dept = dept ; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行结果如下:
雇员编号:0,姓名:null,工资:0.0,部门:null 雇员编号:4555,姓名:无名氏,工资:0.0,部门:未定 雇员编号:6542,姓名:小王,工资:1000.0,部门:后勤 雇员编号:4578,姓名:小明,工资:12000.0,部门:技术部1
2
3
4
这种构造方法的互相调用是在对象实例化的时候,不同的构造有一些相同操作的情况下去使用。
三、this表示当前对象
当前对象,是指当前正在调用类中方法的对象。
先来看一段代码:
package com.wz.thisdemo; class Book{ } public class TestDemo { public static void main(String args[]) { Book booka = new Book(); System.out.println(booka); Book bookb = new Book(); System.out.println(bookb); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行结果:
com.wz.thisdemo.Book@15db9742 com.wz.thisdemo.Book@6d06d69c1
2
在Book类中加上一个打印this的方法:
package com.wz.thisdemo; class Book{ public void print(){ //this就是当前调用该方法的对象 System.out.println("this = "+ this); } } public class TestDemo { public static void main(String args[]) { Book booka = new Book(); System.out.println(booka); booka.print(); System.out.println(); Book bookb = new Book(); System.out.println(bookb); bookb.print(); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
运行结果:
com.wz.thisdemo.Book@15db9742 this = com.wz.thisdemo.Book@15db9742 com.wz.thisdemo.Book@6d06d69c this = com.wz.thisdemo.Book@6d06d69c1
2
3
4
5
那么,之前的“this.属性”实际上就是当前对象的属性,一定是堆内存中保存的内容。
相关文章推荐
- Java学习笔记---Static、静态关键字、详解
- Java学习笔记(19)--关键字static详解
- Java学习笔记(3)——关键字this的使用
- Java 学习笔记(27)--super关键字详解
- Java学习笔记(29)--final关键字详解
- Java学习6:this(隐式参数)关键字内存分析详解及用法
- [java学习笔记]java语言核心----面向对象之this关键字
- java学习笔记之this关键字
- 【安卓学习笔记】JAVA基础Lesson5-关键字this
- 黑马程序员 java学习笔记之一(java中this和super关键字的用法)
- android 学习笔记(四) 4.2 java语法中的关键关键字 final
- 【JAVA学习笔记】01 标志符号、关键字、类型
- 【Java学习笔记】Day 4-2 Static 关键字及Java内存区域
- Java学习笔记之JFreeChart详解
- Java与Flex学习笔记(18)----Flex中创建右键菜单
- Java中的关键字static、this、super、final详解
- Java学习笔记之Pattern类的用法详解(正则表达式)
- Java多线程设计模式详解学习笔记——Introduction1 Java语言的线程
- java学习笔记(static和final关键字)
- 【JAVA学习笔记】01 标志符号、关键字、类型