JAVA 中的非访问修饰符

学习目标:

JAVA 中的非访问修饰符

学习内容:

1. 什么是Java非访问修饰符?

   不用于控制类、成员变量、方法访问权限的一些特定功能标识符。
   例如:static、abstract、final、synchronized、volatile、transient。

2. static
static 关键字
含义: 静态的,全局的
用途: 用于修饰类、方法、变量和代码块。

静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。
静态变量也被称为类变量。局部变量不能被声明为 static 变量。

静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。
静态方法从参数列表得到数据,然后计算这些数据。

静态代码块:
用static修饰的代码块也叫静态代码块,是在类中独立于类成员的static语句块,它不在任何的方法体内,可以有多个,位置可以随便放,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。
即: 静态代码块在类加载时只执行一次。先与构造函数执行。

描述: static关键字表示静态的,全局的可以用来修饰类、方法、变量和代码块。
在通常的开发中最常见的是用static修饰的成员变量和成员方法,被static修饰的成员变量和成员方法独立于该类的任何对象。
也就是说,它不依赖类特定的实例,被类的所有实例共享。
只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们。
因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象,可以通过类名加“.”进行直接访问。

无论是变量,方法,还是代码块,只要用static修饰,就是在类被加载时就已经"准备好了",也就是可以被使用或者已经被执行,都可以脱离对象而执行。
反之,如果没有static,则必须要依赖于对象实例。

特性:
如果一个类要被声明为static的,只有一种情况,就是静态内部类。
静态内部类可以声明普通成员变量和方法,而普通内部类不能声明static成员变量和方法。

用static修饰的方法,只能调用static变量和static方法,不能以任何形式引用this和super,是抽象方法abstract
用static修饰的变量,在定义时必须要进行初始化,且初始化时间要早于非静态变量。

3. abstract
抽象类:
抽象类 不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。
如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法 和 非抽象方法。

抽象方法:
抽象方法是一种 没有任何实现的方法,该方法的具体实现由子类提供。
抽象方法不能被声明成 final 和 static。
任何继承抽象类的 子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。
抽象类可以不包含抽象方法。
抽象方法的声明以分号结尾。(;)
提供限制来不实例化抽象类,这样就需要任何使用该抽象类的人来实现它,并提供多态性。

4. final
final 类不能被继承,没有类能够继承 final 类的任何特性。
final 变量一旦被赋值就不能被改变。
final 方法不能被重写(可以被重载)
注意:
对于 引用类型 来说, “不可变” 说的是 地址不可变
对于 基本类型 来说, “不可变” 说的是 数据不可变

5. synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。
synchronized 修饰符可以应用于四个访问修饰符。

synchronized 修饰符在多线程程序中对临界区代码的访问进行控制。
synchronized关键字是保持代码线程安全的工具之一。
对于某一对象的一个同步方法进行交叉访问是不可能的。
当一个线程在执行某一对象的同步方法时,所有调用该同步方法的其它线程都将被阻塞到第一个线程完成对该方法的调用。

其次,当一个同步方法执行结束时,对相同对象的后续同步方法调用,它会自动建立之前发生的顺序关系。这保证了该对象的状态更改对所有的线程都可见。
当你将一段代码块标记为同步化时,你需要使用对象作为该同步块的参数。当一个执行线程到达该代码块时,它首先需要等待在该对象的同步块上已经没有其它的执行线程。然而,一个线程可以进入不同对象锁定的同步方法块。
但对于同一对象的非同步方法可以直接方法而无需锁检测。
如果你同步化的是静态方法,那么你同步时获取的是该方法类的锁而不是实例的。这就意味着当你同步的是静态方法时,整个类都将被阻塞。这样其它的静态同步方法也将被阻塞。
当一个线程进入同步化实例的方法时,其它线程则不能够在进入该实例的其它同步化方法。
当一个线程进入同步化的静态方法时,其它线程将不能够再进入该类的其它同步化静态方法。

注意:同步化的静态方法和同步化的非静态方法之间是没有多少联系的。如果静态和非静态同步方法能够并发的执行,就需要将你的非静态方法显示的声明为在它自己的类上进行同步。

6. transient 修饰符
序列化的对象包含被 transient 修饰的实例变量时, java虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

7. volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。
而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。


学习产出:

知识总结:

一、volatile 和 synchronize 之间的区别:

  • 1、 volatile 关键字只用来在线程内存和主内存之间同步单个变量值,synchronized 关键字用来同步线程内存和主内存之间的所有变量值以及如何锁定和释放一个监视器。
  • 2、synchronized 比 volatile 有着更大的开销。
  • 3、volatile 变量不允许出现和当前内存中的数据值不同的本地副本。
  • 4、更准确的来说,被声明为 volatile 的变量必须保证它的数据值在所有线程中是同步的。也就是当你在任一线程中访问或者更新一个变量时,所有其它线程能够立即访问到相同的值。
    二、小结
  • 1、static 修饰符同于创建类方法和变量。
  • 2、final 修饰符用于完成类,方法和变量的实现。
  • 3、abstract 修饰符用于创建抽象类和方法。
  • 4、synchronized 和 volatile 修饰符,用于线程。
  • 5、synchronized 关键字声明的方法同一时间只能被一个线程访问。
  • 6、synchronized 修饰符可以应用于四个访问修饰符。
  • 7、一个 volatile 对象引用可能是 null。
  • 8、序列化的对象包括被 transient 修饰的实例变量时,java虚拟机(JVM)跳过该特定的变量。

猜你喜欢

转载自blog.csdn.net/YHLSunshine/article/details/128495710