美文网首页
java中this的几种用法

java中this的几种用法

作者: Stalary | 来源:发表于2018-02-06 22:17 被阅读0次

今天来分析一下Java中this关键字

this的几种用法

调用其他构造函数

public class ThisDemo {

    private int age;

    private String name;

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

    public ThisDemo() {
        this.age = 18;
    }
}

这里我们使用一个含参的构造函数调用了一个无参构造函数。有一点需要我们注意:
使用this()调用构造器,必须要放在第一行,如果可以放在其他行,当ThisDemo存在父类Father时,实例化过程如下:

  • 第一行没有this()或者super(),默认执行super()
  • 完成对父类对象的初始化
  • 返回到子类构造函数继续执行
  • 此时调用this(),将会再次调用super(),再次对父类对象初始化,这样就会产生两个对象,造成了资源的浪费

所以java为了保持对象的合理性,是禁止这种操作的。

获取当前对象的引用

public class ThisDemo {

    private String name;
    
    public void setName(String name) {
        this.name = name;
    }
}

这里我们调用了this的name属性,在方法中将形参name传递给成员变量name,使用this可以便于区分成员变量和局部变量,提高代码的可读性。

代表自身对象

public class ThisDemo {

    private String name;
    
    private String age;
    
    public ThisDemo setName(String name) {
        this.name = name;
        return this;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public static void main(String[] args) {
        ThisDemo demo = new ThisDemo();
        demo.setName("stalary").setAge(21);
    }

这里我们使用this来返回的当前的对象,可以把这个this当成一个类型为该类类型,名称为this的隐含成员变量。

引用溢出

@Data
class FinalReferenceEscape{

    final int i;

    int age;

    static FinalReferenceEscape object;

    public FinalReferenceEscape() {
        i = 1; // 写final域
        this.age = 18;
        object = this;// this引用溢出
    }

    public static void write() {
        new FinalReferenceEscape();
    }

    public static void read() {
        if (object != null) {
            System.out.println(object.i);
        }
    }

    public static void main(String[] args) {
        new Thread(() -> FinalReferenceEscape.write()).start();
        new Thread(() -> FinalReferenceEscape.read()).start();
        System.out.println(FinalReferenceEscape.object);
    }

}

结果

1
FinalReferenceEscape(i=1, age=18)

虽然写final域的重排序规则是可以确保的。
但是要除了要保证在引用变量为任意线程可见之前,该引用变量指向的对象的final域已经在构造函数中被正确初始化过,而且在构造函数内部,不能让这个引用为其他线程所见(对象引用不能在构造函数中溢出)

在上面的代码中:
一个线程执行write,一个线程执行read,这时就可能会发生下图的执行顺序


重排序.png

上图表示,在构造函数还没完成时,就已经读取到了不为null的对象,构造函数中的this造成了引用的溢出。
所以,在构造函数返回前,被构造对象的引用不能为其他线程可见,因为此时的 final 域可能还没有被初始化。

主要参考资料:

《Java并发编程的艺术》

相关文章

  • java中this的几种用法

    今天来分析一下Java中this关键字 this的几种用法 调用其他构造函数 这里我们使用一个含参的构造函数调用了...

  • Java中indexOf()的几种用法

    参考:Java indexOf() 方法 indexOf() 方法有以下四种形式: public int inde...

  • Java foreach循环使用详解[转]

    本文转自码农网 本文非常适合初学Java的程序员,主要是来了解一下Java中的几种for循环用法,分析得十分详细,...

  • Java for循环的几种用法

    Java中经常用到for循环、while循环、do...while循环,这里简单分析这三中循环语句的的使用区别 p...

  • Java @ synchronized

    参考: Java中Synchronized的用法 Java 多线程:synchronized 关键字用法(修饰类,...

  • Java for循环的几种用法详解

    本文非常适合初学Java的程序员,主要是来了解一下Java中的几种for循环用法,分析得十分详细,一起来看看。 J...

  • 浅谈java内置锁synchronized

    1、synchronized使用 synchronized是java提供的关键字,用来实现同步,主要用法有以下几种...

  • java学习之时间戳的使用

    时间戳在代码中经常用到,也算是比较重要的概念了,下面就总结一下时间戳在java中的几种用法 -----------...

  • synchronized的使用方式

    synchronized是Java中的关键字,是一种同步锁。它通常有以下几种用法: 修饰一个代码块,被修饰的代码块...

  • Java面试

    Java中Synchronized的用法Java面试准备Java HashMap 源码解析Java 位运算(移位、...

网友评论

      本文标题:java中this的几种用法

      本文链接:https://www.haomeiwen.com/subject/ogynzxtx.html