📓
Be a Javaer
  • Introduction
  • 第 1 章 Java编程开发入门
    • 第 1 节 Java开发准备
    • 第 2 节 Java基本概念
    • 第 3 节 Java数据类型划分
    • 第 4 节 Java运算符
    • 第 5 节 Java程序逻辑控制
    • 第 6 节 Java方法的定义及使用
  • 第 2 章 Java面向对象编程
    • 第 1 节 类与对象
    • 第 2 节 深入分析类与对象
    • 第 3 节 数组的定义与使用
    • 第 4 节 String类的基本概念
    • 第 5 节 String类的常用方法
    • 第 6 节 this关键字
    • 第 7 节 引用传递
    • 第 8 节 数据表与简单Java类映射
    • 第 9 节 对象比较
    • 第 10 节 static关键字
    • 第 11 节 代码块
    • 第 12 节 内部类
    • 第 13 节 链表的定义与使用
    • 第 14 节 继承性
    • 第 15 节 覆写
    • 第 16 节 数组操作
    • 第 17 节 辅助概念
      • final关键字
      • 多态性
    • 第 18 节 抽象类的定义及使用
    • 第 19 节 接口的定义及使用
    • 第 20 节 Object类
    • 第 21 节 拓展概念
      • 匿名内部类
      • 包装类
    • 第 22 节 包的定义及使用
    • 第 23 节 访问控制权限
      • 单例设计模式
      • 多例设计模式
    • 第 24 节 异常的捕获及处理
    • 第 25 节 Java5新特性
      • 可变参数
      • foreach循环
      • 静态导入
    • 第 26 节 泛型
    • 第 27 节 枚举
    • 第 28 节 Annotation
    • 第 29 节 Java7新特性
      • AutoCloseable
      • Try-with-resources
    • 第 30 节 Java8新特性
      • 接口定义增强
      • Lambda表达式
      • 方法引用
      • 函数式接口
  • 第 3 章 Java高级编程
    • 第 1 节 Java多线程基础实现
    • 第 2 节 线程常用操作方法
    • 第 3 节 线程的同步与死锁
    • 第 4 节 生产者与消费者
    • 第 5 节 Java基础类库
      • StringBuffer
      • Runtime
      • System
      • finalize
      • Cleaner
      • 对象克隆
    • 第 6 节 数字操作类
      • Math类
      • Random类
      • 大数字操作类
    • 第 7 节 日期处理类
      • Date类
      • 日期格式化
      • Calendar类
    • 第 8 节 比较器
    • 第 9 节 正则表达式
      • 常用的正则标记
      • String类对正则的支持
      • java.util.regex包支持
    • 第 10 节 反射机制
    • 第 11 节 动态代理
    • 第 12 节 反射与Annotation
    • 第 13 节 国际化程序实现
    • 第 14 节 开发支持类库
      • Arrays类
      • UUID类
      • Optional类
      • ThreadLocal类
      • 定时器
      • Base64加密工具
    • 第 15 节 文件操作
    • 第 16 节 字节流与字符流
    • 第 17 节 IO辅助概念
      • 字符编码
      • 内存流
      • 管道流
      • RandomAccessFile
    • 第 18 节 打印流
    • 第 19 节 System类对IO的支持
    • 第 20 节 对象序列化
    • 第 21 节 IO高级应用
      • 缓冲输入流
      • Scanner
    • 第 22 节 网络编程
    • 第 23 节 类集框架
    • 第 24 节 List集合
    • 第 25 节 集合输出
    • 第 26 节 Map集合
    • 第 27 节 Set集合
    • 第 28 节 集合工具类
      • Stack
      • Queue
      • Properties
      • Collections工具类
    • 第 29 节 数据流Stream
    • 第 30 节 JDBC简介
    • 第 31 节 Statement接口
    • 第 32 节 PreparedStatment接口
    • 第 33 节 批处理与事务处理
  • 第 4 章 Oracle数据库基础
    • 第 1 节 Oracle简介
    • 第 2 节 Oracle安装与配置
    • 第 3 节 SQLPlus命令
    • 第 4 节 SQL简介与数据表分析
    • 第 5 节 SQL简单查询
    • 第 6 节 SQL限定查询
    • 第 7 节 查询排序
    • 第 8 节 综合练习:基础查询
    • 第 9 节 单行函数
    • 第 10 节 多表查询
    • 第 11 节 分组统计查询
    • 第 12 节 子查询
    • 第 13 节 综合案例:复杂查询
    • 第 14 节 数据更新操作
    • 第 15 节 事务处理
    • 第 16 节 数据伪列
    • 第 17 节 数据表的创建与管理
    • 第 18 节 约束的创建与管理
    • 第 19 节 综合案例:数据表操作
    • 第 20 节 序列的定义与使用
  • 第 5 章 JavaWeb基础
  • 第 6 章 走向单体地狱
  • 第 7 章 GitFlow工作流指南
    • 版本控制
    • Git
    • 集中式工作流
    • 功能分支工作流
    • GitFlow 工作流
    • Forking 工作流
    • Pull Requests
  • 第 8 章 微服务入门
    • 第 1 节 微服务简介
    • 第 2 节 Linux
    • 第 3 节 Docker
    • Docker 仓库
    • Ubuntu 安装 Docker
    • Docker 镜像加速器
    • 第 4 节 Docker Compose
    • 第 5 节 GitLab
    • 第 6 节 Nexus
    • 第 7 节 Harbor
  • 第 9 章 再谈微服务
  • 第 10 章 Spring Boot
  • 第 11 章 Spring Cloud Netflix
  • 第 12 章 Apache Dubbo Zookeeper
  • 第 13 章 Spring Cloud Alibaba
  • 第 14 章 Vue
  • 第 15 章 Kubernetes
  • 第 16 章 Spring Security oAuth2
  • 第 17 章 Flutter
  • Redis
    • Redis 入门
    • Redis 的数据类型
    • Redis 事务
    • Jedis
    • Spring Boot 整合 Redis
    • Redis 配置文件
    • Redis 持久化
    • Redis 发布/订阅
    • Redis 主从复制
    • Redis Sentinel
    • Redis 缓存故障
  • Glossary
由 GitBook 提供支持
在本页
  • 调用属性
  • 调用方法
  • 表示当前对象
  • 总结

这有帮助吗?

  1. 第 2 章 Java面向对象编程

第 6 节 this关键字


this关键字是Java中比较复杂的一个关键字,因为this有一个核心概念:当前对象,而这个当前对象就很难去理解。

在Java里面,利用this关键字可以实现类属性的调用、类方法的调用、表示当前对象。

调用属性

下面来观察如下的一段代码。

范例: 观察程序

class Book {
    private String title;
    private double price;
    public Book(String t, double p) {
        title = t;
        price = p;
    }
    //setter、getter略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    } 
}
public class MainClass {
    public static void main(String[] args) {
        Book book = new Book("Java基础入门", 89.8);
        System.out.println(book.getInfo());
    }
}

观察如下的一点:

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

此处使用的是一个构造方法,而这个构造方法的主要功能是为title与price初始化使用,但是方法中的参数名称无法

起到“见名知意”的效果。既然构造方法中的参数的目的是为了类中的属性初始化,那么最好的做法是直接将参数设

置为与属性名称保持一致。

public Book(String title, double price) {
    title = title;
    price = price;
}

修改为以上的形式参数就比较合理,但是最终发现在构造方法传递的参数内容并没有传递到属性之中。

在Java程序里面它是以“{}”为界限。如果现在属性名称与参数名称出现了重名的情况下,默认情况如果没有加入任

何的限制,值得都是最近的“{}”内的变量名称。所以在这种情况下为了可以明确的找到要访问的变量属于类中的属

性的时候,需要在变量前加上this,这样就可以准确的进行属性的标记。

class Book {
    private String title;
    private double price;
    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }
    //setter、getter略
    public String getInfo() {
        return "书名:" + this.title + ",价格:" + this.price;
    } 
}
public class MainClass {
    public static void main(String[] args) {
        Book book = new Book("Java基础入门", 89.8);
        System.out.println(book.getInfo());
    }
}

在以后程序开发之中,只要是访问类中的属性前面必须加上“this.”。

调用方法

通过之前的代码可以发现,所谓的this实际上指的就是本类的结构,在一个类中除了有成员之外还会有方法(普通方法、构造方法),利用this可以调用本类的普通方法或构造方法。

调用普通方法

class Book {
    private String title;
    private double price;
    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }
    //setter、getter略
    public void print() {
        System.out.println("**********");
    }
    public String getInfo() {
        this.print();
        return "书名:" + this.title + ",价格:" + this.price;
    } 
}
public class MainClass {
    public static void main(String[] args) {
        Book book = new Book("Java基础入门", 89.8);
        System.out.println(book.getInfo());
    }
}

调用普通方法的时候是否在方法前加入“this.”并没有一个明确的要求,即使不加this也表示本类调用的方法,但是从代码的严谨性上来讲一定要加上this。

调用构造方法

一个类中除了普通方法还有构造方法,可以通过this()调用本类的构造方法,如果要调用有参构造则在参数列表中提供相应的参数即可。

this调用构造的作用主要是在多个构造方法之间进行相互调用,下面将通过一个简短的代码来分析,为什么需要构造方法间的相互调用。

范例: 观察问题

现在定义的Book类里面有三个构造方法,但是要求不管调用哪一个构造方法都要输出一行提示信息“新的Book类对象生成”。

class Book {
    private String title;
    private double price;
    public Book() {
        System.out.println("一个新的Book类对象生成");
    }
    public Book(String title) {
        System.out.println("一个新的Book类对象生成");
        this.title = title;
    }
    public Book(String title, double price) {
        System.out.println("一个新的Book类对象生成");
        this.title = title;
        this.price = price;
    }
    //setter、getter略
    public String getInfo() {
        return "书名:" + this.title + ",价格:" + this.price;
    } 
}
public class MainClass {
    public static void main(String[] args) {
        Book book = new Book("Java基础入门", 89.8);
        System.out.println(book.getInfo());
    }
}

此时代码里面出现有重复代码,必须想办法消除重复。

class Book {
    private String title;
    private double price;
    public Book() {
        System.out.println("一个新的Book类对象生成");
    }
    public Book(String title) {
        this();
        this.title = title;
    }
    public Book(String title, double price) {
        this(title);
        this.price = price;
    }
    //setter、getter略
    public String getInfo() {
        return "书名:" + this.title + ",价格:" + this.price;
    } 
}
public class MainClass {
    public static void main(String[] args) {
        Book book = new Book("Java基础入门", 89.8);
        System.out.println(book.getInfo());
    }
}

虽然以上实现了构造方法间的相互调用,但是依然会存在一些限制:

  • 使用“this()”调用构造方法形式的代码只能够放在构造方法的首行

  • 进行构造方法相互调用的时候,一定要保留调用的出口。

范例: 观察错误的代码

class Book {
    private String title;
    private double price;
    public Book() {
        this("Java", 89.8);
        System.out.println("一个新的Book类对象生成");
    }
    public Book(String title) {
        this();
        this.title = title;
    }
    public Book(String title, double price) {
        this(title);
        this.price = price;
    }
    //setter、getter略
    public String getInfo() {
        return "书名:" + this.title + ",价格:" + this.price;
    } 
}
public class MainClass {
    public static void main(String[] args) {
        Book book = new Book("Java基础入门", 89.8);
        System.out.println(book.getInfo());
    }
}

以上代码在编译之后就会出现错误提示“构造方法递归调用”,所以在使用this()互相调用构造的时候至少保留一个构造没有使用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;
    }
    //setter、getter略
    public String getInfo() {
        return "雇员编号:" + this.empno + ",名称:" + this.ename + ",工资:" + this.sal + ",部门:" + this.dept;
    }
}
public class MainClass {
    public static void main(String[] args) {
        Emp ea = new Emp();
        Emp eb = new Emp(9527);
        Emp ec = new Emp(7566, "ALLEN");
        Emp ed = new Emp(7869, "KING", 5000.0, "Boss");
        System.out.println(ea.getInfo());
        System.out.println(eb.getInfo());
        System.out.println(ec.getInfo());
        System.out.println(ed.getInfo());
    }
}

虽然以上的代码完成了功能,但是却存在有重复的操作,很明显,这种代码不符合实际的开发要求。

**实现方式二:**利用构造方法简化代码

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;
    }
    //setter、getter略
    public String getInfo() {
        return "雇员编号:" + this.empno + ",名称:" + this.ename + ",工资:" + this.sal + ",部门:" + this.dept;
    }
}
public class MainClass {
    public static void main(String[] args) {
        Emp ea = new Emp();
        Emp eb = new Emp(9527);
        Emp ec = new Emp(7566, "ALLEN");
        Emp ed = new Emp(7869, "KING", 5000.0, "Boss");
        System.out.println(ea.getInfo());
        System.out.println(eb.getInfo());
        System.out.println(ec.getInfo());
        System.out.println(ed.getInfo());
    }
}

此时的操作就利用了构造方法间的相互调用解决了代码的重复问题。

表示当前对象

当前对象指的是当前正在调用类中方法的对象。

class Book {
	public void print() {
		//this就是当前调用方法的对象
		System.out.println("this = " + this);
	}
}
public class MainClass {
	public static void main(String[] args) {
		Book booka = new Book();
		Book bookb = new Book();
		System.out.println("booka = " + booka);
		booka.print();
		System.out.println("----------------------------");
		System.out.println("bookb = " + bookb);
		bookb.print();
	}
}

之前出现的“this.属性”实际上指的就是当前对象中的属性,一定是保存在堆内存中的内容。

**思考:**观察如下代码的执行

class A {
	private B b;
	//2、执行A()
	public A() {
		//3、实例化B类对象
		this.b = new B(this); //4、this == temp
		this.b.get(); //7、调用b.get()
	}
	//10、调用print()
	public void print() {
		System.out.println("Hello World !");
	}
}
class B {
	private A a;
	//5、调用B(A a),a == temp
	public B(A a) {
		this.a = a; //6、保存a对象(temp)
	}
	//8、调用this.a(temp).print()
	public void get() {
		this.a.print();
	}
}
public class MainClass {
	public static void main(String[] args) {
		//1、实例化A类对象,调用A()
		A temp = new A();
	}
}

总结

1、类中的属性调用一定要加上this;

2、类中的构造方法间的互相调用一定要保留出口;

3、this表示当前对象,指的是当前正在调用类中方法的对象。

上一页第 5 节 String类的常用方法下一页第 7 节 引用传递

最后更新于5年前

这有帮助吗?