Java编程中this和static关键字的用法详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenbaige/article/details/79423647

前言:在平时的编码过程中,相信大家都会频繁地使用到this或static关键字。但可能你仅仅是了解它的用法,而对其内部机制知之甚少。今天我们就一起来探讨一下它们的内部机制。

一.this关键字的详解
首先我们来总结一下this常见的应用场景,下面我们定义一个User类,基本包含了我们常见的this的用法,如下所示:

public class User {

    private String name;

    private int age;

    public User(String name) {
        this.name = name;
    }

    public User(String name, int age) {
        this(name);
        this.age = age;
    }

    /**
     * 打印名称
     */
    private void printName() {
        System.out.println(name);
    }

    /**
     * 打印年龄
     */
    private void printAge() {
        System.out.println(age);
    }

    /**
     * 打印名称
     */
    private void print() {
        this.printName();
        this.printAge();
    }

    /**
    *修改信息并返回对象
    */
    private User updateName(String name){
        this.name = name;
        return this;
    }
}
  • 场景一:应用this在成员变量上
 public User(String name) {
        this.name = name;
    }

在这种情况下,由于自变量name的名字以及成员数据name 的名字是相同的,所以会出现混淆。为解决这个问题,可用 this.name 来引用成员数,经常都会在 Java 代码里看到这种形式的应用。this是指当前对象,this.name是指当前对象的成员变量name。

  • 场景二:构造器里使用this调用构造器
 public User(String name, int age) {
        this(name);
        this.age = age;
    }

若为一个类写了多个构建器,那么经常都需要在一个构建器里调用另一个构建器,以避免写重复的代码。在User类中,两个参数的构造器就通过this调用了一个参数的构造器。

this通常是指“这个对象”或者“当前对象”。而且它本身会产生当前对象的一个句柄。在一个构建器中,若为其赋予一个自变量列表,那么 this 关键字会具有不同的含义:它会对与那个自变量列表相符的构建器进行明确的调用。这样一来,我们就可通过一条直接的途径来调用其他构建器。构建器调用必须是我们做的第一件事情,否则会收到编译程序的报错信息

  • 场景三:方法中通过this调用方法
 private void print() {
        this.printName();
        this.printAge();
    }

在print方法内调用printName方法。我们可以用this.printName(),亦可以直接调用printName()。事实上,这里的this是没必要的,编译器能帮我们自动完成。

  • 场景四:通过this获取当前对象
 private User updateName(String name){
        this.name = name;
        return this;
    }

在这个方法中,我们先改变了成员变量name的值,接下来调用了return this代码。这里的this是返回了当前对象相应的句柄,也就是返回的对象和原调用对象其实是一个对象,在堆中都指向同一片内存地址。这个我们可以通过代码进行验证:

//测试代码
   public static void main(String[] args) {

        User user = new User("hello");
        System.out.println("old:" + user);
        System.out.println(user.getName());

        User user1 = user.updateName("world");
        System.out.println("new:" + user1);
        System.out.println(user.getName());
    }

首先创建了一个user对象,给对象的name变量赋值为hello,打印的结果应该是user对象的地址和name名称hello。

接下来,我们通过updateName方法修改对象的那么变量值为world,如果我们上面结论成立,打印的user1对象地址应给和user的地址一样,对象的name变量值应该为world。

结果和我们的预期一样,因此上面的结论是正确的:通过this返回的是当前对象相应的句柄,即是方法调用对象的句柄。结果如下:

old:com.cbg.User@511d50c0
hello
new:com.cbg.User@511d50c0
world

重要:如果再进一步探究内部的原理,可以从user对象调用updateName方法入手。我们在Java代码中一般的调用方式是:user.updateName("world"),但是编译器还会在内部为我们完成一些幕后工作,将上面的代码转化为如下的调用方式:User.updateName(user,"world"),也就是说,上面两行代码是等效的。只是,一个是我们平常调用的,一个事编译器调用的。但是,第二种方式是内部的表达形式,我们并不能这样书写表达式,并试图让编译器接受它。到这里,我们就明白,其实要得到user的句柄,在编译器内部其实就是那么简单,也就解释了地址相同的问题。其实,返回的user1对象,就是改变了name属性的user对象。

二.static关键字的详解

将this和static放在一起,是因为我们可以在对比中进行更深刻的理解。

  1. 由static修饰的方法或字段,都是属于类级别的。而this指代的是当前对象(对象级别)。意味着在static修饰的特定的方法中不存在this。
    注意:利用 static 方法,我们不必向对象发送一条消息,因为不存在 this。
  2. 我们不可从一个 static 方法内部发出对非 static 方法的调用(特例:我们将一个对象句柄传到static 方法内部。这时,在static方法内部,会获取到这个对象的句柄(上文中的this)。通过这个句柄,我们可调用非 static 方法,并访问非 static 字段)。
  3. 在没有任何对象的前提下,我们可针对类本身发出对一个 static 方法的调用。

三.总结: 到这里,相信大家对this和static的用法都有了或深或浅的理解,还有更多的关于它们的用法,就需要自己去探索发散啦!也可以留言,一起探讨。最后,希望对大家有帮助额!!

猜你喜欢

转载自blog.csdn.net/chenbaige/article/details/79423647