一、final
1、fianl可以修饰的内容
①修饰变量
- 如果是基本数据类型(int,double,char)变量那么表示这个变量是不可变的,即表示一个常量,通常是大写
- 如果是引用类型(String,Date,Animal,Person)的变量那么表示这个引用只能指向初始化时指向的那个对象,不能在执行别的对象,但这个对象的
- fianl修饰的变量一定要有初始化的值且只能初始化一次,否则会报错(还是编译时错误)
②修饰类,表示这个类是最终类,是不可被继承的。abstract与fianl是不能修饰同一个类的,因为当一个类被声明为abstract后就是要被用来继承,与fianl搭配是互相矛盾的。常见的fianl类有System,String…
③修饰方法,那么这个方法就不能被重写,但不影响子类调用父类中的fianl方法,也不影响重载。fianl与abstract不能同时修饰一个方法,原因同②
2 fianl与String的搭配,先看题目
public class Main {
public static void main(String[] args) {
String a = "wzh2";
final String b = "wzh";
String d = "wzh";
String c = b + 2;
String e = d + 2;
System.out.println((a == c));
System.out.println((a == e));
}
}
这段代码的输出结果是什么呢?
答案是: true 和 false
1、变量a指的是字符串常量池中的 wzh2;
2、变量 b 是 final 修饰的,变量 b 的值在编译时候就已经确定了它的确定值,换句话说就是提前知道了变量 b 的内容到底是个啥,相当于一个编译期常量;
3、变量 c 是 b + 2得到的,由于 b 是一个常量,所以在使用 b 的时候直接相当于使用 b 的原始值(wzh)来进行计算,所以 c 生成的也是一个常量,a 是常量,c 也是常量,都是 wzh2 ,而 Java 中常量池中只生成唯一的一个 wzh2 字符串,所以 a 和 c 是相等的!
4、d 是指向常量池中 wzh,但由于 d 不是 final 修饰,也就是说在使用 d 的时候不会提前知道 d 的值是什么,所以在计算 e 的时候就不一样了,e的话由于使用的是 d 的引用计算,变量d的访问却需要在运行时通过链接来进行,所以这种计算会在堆上生成wzh2 ,所以最终 e 指向的是堆上的 wzh2 , 所以 a 和 e 不相等。
总结:a、c是常量池的xiaomeng2,e是堆上的xiaomeng2
3、使用final的好处
- final方法比非final快一些
- final关键字提高了性能。JVM和Java应用都会缓存final变量。
- final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
- 使用final关键字,JVM会对方法、变量及类进行优化。
二、finally
1 用法:通常和try catch搭配使用,保证不管有没有发生异常,资源都能够被释放(释放连接、关闭IO流)
2 搭配return,不多废话,直接看题
public class Test {
public static int test(){
int num = 10;
try {
return num += 80;
}catch (Exception e){
System.out.println(e);
}finally {
if(num > 20){
System.out.println("num>20,num=" +num);
}
return num;
}
}
public static void main(String[] args) {
System.out.println(test());
}
}
结果是:
原因是return num += 80被划分为了两步①num = num + 80② return num;但是在进入fianlly之前只是执行的①而没有执行②,fianlly中的num已经变成了90,执行完fianlly后再执行return,也就是再执行②
public class Test {
public static int test(){
int num = 10;
try {
return num += 80;
}catch (Exception e){
System.out.println(e);
}finally {
num += 20;
return num;
}
}
public static void main(String[] args) {
System.out.println(test());
}
}
返回结果是110,很简单,如果fianlly与try中都有返回值,那么try中的return会被覆盖,不再执行
三、Finalize:
Finalize是object类中的一个方法,子类可以重写finalize()方法实现对资源的回收。垃圾回收只负责回收内存,并不负责资源的回收,资源回收要由程序员完成,Java虚拟机在垃圾回收之前会先调用垃圾对象的finalize方法用于使对象释放资源(如关闭连接、关闭文件),之后才进行垃圾回收,这个方法一般不会显示的调用,在垃圾回收时垃圾回收器会主动调用。