资讯专栏INFORMATION COLUMN

Java基础知识整理之this用法

ZHAO_ / 771人阅读

摘要:分别使用这四个构造器方法去创建对象。出口是指的是我们在创建构造器的时候,不能每一个构造器方法中都使用方法,因为如果全部都使用,程序执行的就会陷入递归调用就会报错。在下面的代码中,我们需要了解的知识是就是指我们当前的调用的构造器方法。

具体内容

在 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 不是一个固定的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76669.html

相关文章

  • Java基础知识整理static应用与总结

    摘要:导入包注意使用了关键字上面使用了关键字之后,可以直接使用中的方法。通过关键字调用有参构造方法控制台输出总结属性和方法可以再没有实例化对象的时候直接由类名称进行调用。属性保存在全局数据区。 前面两篇分别介绍了static的属性以及方法。本篇就做一个收尾,介绍下剩下的。 在之前的总结: 不管多少个对象,都使用同一个 static 属性 使用 static 方法可以避免掉用实例化方法之后才...

    ytwman 评论0 收藏0
  • Java基础知识整理static修饰属性

    摘要:属性声明虽然是在类的结构中,但是并不受到对象的控制,是独立存在的。所修饰的在静态数据区。也就是说,在没有产生实例化对象的情况下,依然可以使用对象。 static 关键字,我们在开发用的还是比较多的。在《Java编程思想》有下面一段话 static 方法就是没有 this 的方法。在 static 方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类...

    张宪坤 评论0 收藏0
  • Java基础知识整理static修饰方法

    摘要:前面一篇已经介绍了部分关于的用法,主要是介绍的是修饰变量的一些知识。现在的这篇介绍下修饰方法。方法调用非方法或者属性错误的调用以下的操作都在下面进行的。只能调用属性或者方法。所有的定于的结构不受实例化对象的控制。 前面一篇已经介绍了部分关于 static 的用法,主要是介绍的是 static 修饰变量的一些知识。现在的这篇介绍下 static 修饰方法。 static 修饰方法 没有实...

    BothEyes1993 评论0 收藏0
  • Java 总结

    摘要:中的详解必修个多线程问题总结个多线程问题总结有哪些源代码看了后让你收获很多,代码思维和能力有较大的提升有哪些源代码看了后让你收获很多,代码思维和能力有较大的提升开源的运行原理从虚拟机工作流程看运行原理。 自己实现集合框架 (三): 单链表的实现 自己实现集合框架 (三): 单链表的实现 基于 POI 封装 ExcelUtil 精简的 Excel 导入导出 由于 poi 本身只是针对于 ...

    caspar 评论0 收藏0
  • 工具使用-积累与发现

    摘要:一积累中如何快速查看包中的源码最常用的大开发快捷键技巧将对象保存到文件中从文件中读取对象中的用法的配置详解和代码的格式详解格式化内容设置生成详解注释规范中设置内存调试的小知识单步执行命令的区别的动态代理机制详解内容有瑕疵,楼指正泛型继承的几 一、积累 1.JAVA Eclipse中如何快速查看jar包中 的class源码 最常用的15大Eclipse开发快捷键技巧 Java将对象保存到...

    wangjuntytl 评论0 收藏0

发表评论

0条评论

ZHAO_

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<