-
final关键字
final关键字在java中使用非常广泛,可以申明成员变量、方法、类、本地变量。一旦将引用声明为final,将无法再改变这个引用。final关键字还能保证内存同步 。
-
final的使用
final变量有成员变量或者是本地变量(方法内的局部变量),在类成员中final经常和static一起使用,作为类常量使用。其中类常量必须在声明时初始化,final成员常量可以在构造函数初始化。 是不是类变量这个是由static关键字决定的。
final修饰基本数据类型时代表不能修改这个基本数据类型变量的值,修饰应用的时候代表不能修改这个引用指向的对象。
final方法表示该方法不能被子类的方法重写,将方法声明为final,在编译的时候就已经静态绑定了,不需要在运行时动态绑定。final方法调用时使用的是invokespecial指令。
final类不能被继承,final类中的方法默认也会是final类型的,java中的String类和Integer类都是final类型的。
-
final关键字
- final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。final变量一旦被初始化后不能再次赋值。
- 本地变量必须在声明时赋值。 因为没有初始化的过程
- 在匿名类中所有变量都必须是final变量。
- final方法不能被重写, final类不能被继承
- 接口中声明的所有变量本身是final的。类似于匿名类
- final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
- final方法在编译阶段绑定,称为静态绑定(static binding)。
- 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
使用final的好处:
- 提高了性能,JVM在常量池中会缓存final变量(比如String)
- final变量在多线程中并发安全,无需额外的同步开销
- final方法是静态编译的,提高了调用速度,所谓静态编译就是相当于c++中的内连方法,在编译的时候直接把调用的方法换到被调用的地方。
- final类创建的对象是只可读的,在多线程可以安全共享
-
final的最佳实践
final方法的三条规则
规则1:final修饰的方法不可以被重写。
规则2:final修饰的方法仅仅是不能重写,但它完全可以被重载。
规则3:父类中private final方法,子类可以重新定义,这种情况不是重写。
final和jvm的关系:
对于 final 域,编译器和处理器要遵守两个重排序规则:
- 在构造函数内对一个 final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。
- 初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序。
写 final 域的重排序规则禁止把 final 域的写重排序到构造函数之外。这个规则的实现包含下面 2 个方面:
- JMM 禁止编译器把 final 域的写重排序到构造函数之外。
- 编译器会在 final 域的写之后,构造函数 return 之前,插入一个 StoreStore 屏障。这个屏障禁止处理器把 final 域的写重排序到构造函数之外。
这些点在jvm中都有讲到。
读 final 域的重排序规则如下:
- 在一个线程中,初次读对象引用与初次读该对象包含的 final 域,JMM 禁止处理器重排序这两个操作(注意,这个规则仅仅针对处理器)。编译器会在读 final 域操作的前面插入一个 LoadLoad 屏障。
这条规则是为了防止读final域之前整个对象都还没有初始化,读出来的final数据也将是没有初始化的。
-
-
static关键字
static关键字有以下四种使用场景
- 修饰成员变量和成员方法
- 静态代码块
- 修饰类(只能修饰内部类)
- 静态导包
最常用来修饰成员变量和成员方法
修饰成员变量和方法:
被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。
静态代码块:
静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。 该类不管创建多少对象,静态代码块只执行一次. 可以有多个静态静态代码块,执行的时候按照顺序执行。
静态内部类:
对于普通的内部类,创建的时候会 隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着:
- 它的创建是不需要依赖外围类的创建。
- 它不能使用任何外围类的非static成员变量和方法。
静态内部类只有当自己的成员变量或者方法被引用的时候才会被加载。
静态方法和普通方法的区别:
静态方法属于类对象,普通方法属于实例。
静态方法可以使用类名和实例名调用方法,普通方法只有后者。
静态方法只允许访问静态资源
static{}和{}
相同点: 都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些static变量进行赋值。
不同点: 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。
java基础--java中的关键字
最新推荐文章于 2022-10-30 02:25:47 发布