Java关键字总结

文章目录

  • this关键字
  • static关键字
  • super关键字
  • final关键字
  • instanceof关键字
  • volatile关键字
    • volatile的原理和实现机制
    • transient关键字

this关键字

  • this代表所在类的当前对象的引用(地址值),即代表当前对象。
  • this出现在实例方法中,谁调用这个方法(哪个对象调用这个方法),this就代表谁(this就代表哪个对象)。
  • this出现在构造器中,代表构造器正在初始化的那个对象。

static关键字

  1. static 修饰成员变量或者成员方法时,该变量称为静态变量,该方法称为静态方法。该类的每个对象都共享同一个类的静态变量和静态方法。任何对象都可以更改该静态变量的值或者访问静态方法。但是不推荐这种方式去访问。因为静态变量或者静态方法直接通过类名访问即可,完全没有必要用对象去访问。
  2. 无static修饰的成员变量或者成员方法,称为实例变量,实例方法,实例变量和实例方法必须创建类的对象,然后通过对象来访问。
  3. static修饰的成员属于类,会存储在静态区,是随着类的加载而加载的,且只加载一次,所以只有一份,节省内存。存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。它优先于对象存在,所以,可以被所有对象共享。
  4. 无static修饰的成员,是属于对象,对象有多少个,他们就会出现多少份。所以必须由对象调用。

super关键字

  • 子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用super 关键字,修饰父类成员变量,类似于 this
  • 需要注意的是:super代表的是父类对象的引用,this代表的是当前对象的引用。

final关键字

  • final: 不可改变,最终的含义。可以用于修饰类、方法和变量。
    • 类:被修饰的类,不能被继承。
    • 方法:被修饰的方法,不能被重写。
    • 变量:被修饰的变量,有且仅能被赋值一次。

instanceof关键字

  • Java提供了 instanceof 关键字,给引用变量做类型的校验,格式如下:
变量名 instanceof 数据类型 
如果变量属于该数据类型或者其子类类型,返回true。
如果变量不属于该数据类型或者其子类类型,返回false

volatile关键字

  • 使用volatile关键字:
   private volatile boolean flag ;

volatile关键字的两层语义

  • 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
    • 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
    • 禁止进行指令重排序。
  • 工作原理:
    Java关键字总结_第1张图片
  1. VolatileThread线程从主内存读取到数据放入其对应的工作内存

  2. 将flag的值更改为true,但是这个时候flag的值还没有写会主内存

  3. 此时main方法main方法读取到了flag的值为false

  4. 当VolatileThread线程将flag的值写回去后,失效其他线程对此变量副本

  5. 再次对flag进行操作的时候线程会从主内存读取最新的值,放入到工作内存中

volatile的原理和实现机制

  • volatile到底如何保证可见性和禁止指令重排序的?

    • 观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令

    • 没添加volatile关键字

    • 在这里插入图片描述

    • 添加volatile关键字Java关键字总结_第2张图片

    • lock前缀指令实际上相当于一个内存屏障(也称内存栅栏),内存屏障会提供3个功能

      • 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
      • 它会强制将对缓存的修改操作立即写入主存;
      • 如果是写操作,它会导致其他CPU中对应的缓存行无效。
  • 总结: volatile保证不同线程对共享变量操作的可见性,也就是说一个线程修改了volatile修饰的变量,当修改写回主内存时,另外一个线程立即看到最新的值。但是volatile不保证原子性

transient关键字

  • 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
  • transient关键字只能修饰变量,而不能修饰方法和类。需要注意,局部变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
  • 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

你知道的越多,你不知道的越多。
有道无术,术尚可求,有术无道,止于术。
如有其它问题,欢迎大家留言,我们一起讨论,一起学习,一起进步

你可能感兴趣的:(java基础)