final修饰符用于声明属性方法和类:
1)用final修饰的类不能被继承。
2)用final修饰的方法不能被子类的方法覆盖。
3)private类型的方法都默认为final方法,因而不能被子类的方法覆盖。
4)final变量必须被显式初始化,而且只能被赋一次值。
对于基本数据类型,final使数值恒定不变,而用于对象引用,final使引用恒定不变,一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然后,对象其自身是可以被修改的。
以下修饰符连用是无意义的,会导致编译错误:
abstract与private、abstract与final、abstract与static。
finally:为确保一段代码不管发生什么异常都会被执行。
在try-catch-finally中, 当return遇到finally:
1.在try catch块里return的时候,finally也会被执行。
2.return 语句会把后面的值复制到一份用来返回,如果return的是值而不是引用,finally里对变量的改动将不起效果,如果 return 的是引用类型的,改动将可以起效果。
3.finally里的return语句会把try catch块里的return语句效果给覆盖掉。
结论:看来return语句并不一定都是函数的出口,执行return时,只是把return后面的值复制了一份到返回值变量里去了。
建议:
1.最好把return放到方法尾而不要在try cath 里return
2.不要在try catch块和finally块里都包含return
3.如果在try catch块里return, 则不要在finally块里操作被return的变量
那么现在有两个问题,当return遇上finally后,finally中的语句一定会执行吗?如果执行,是什么时候执行?
从下面的demo中可以得到答案:
class Demo {
public int test() {
try {
System.out.println("start");
return testTry();
} finally {
System.out.println("finally block");
return 6;
}
}
public int testTry(){
System.out.println("try block");
return 5;
}
public static void main(String[] args) {
Demo d=new Demo();
System.out.println(d.test());
}
}
输出结果:
start
try block
finally block
6
从上面的例子中可以得出以下结论:
1.finally块的语句在try或catch中的return语句执行之后返回之前执行。
2.finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值。
3.若finally里也有return语句则会覆盖try或catch中的return语句直接返回。
4.在try块中有System.exit(0);这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。
finaliza()方法:
java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被对象引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
注意:finalize()方法自身没有清理功能。
下面用例子示范了finalize()可能的使用方式:
class Book {
boolean checkout=false;
public Book(boolean checkout) {
this.checkout=checkout;
}
void checkin(){
checkout=false;
}
//子类的权限必须大于等于父类
protected void finalize(){
if(checkout){
System.out.println("ERROR:check out");
}
}
public static void main(String[] args) {
Book d=new Book(true);
d.checkin();
new Book(true);
//这里我执行了数十次,发现finalize()中的打印语句,没有每次都会打印
System.gc();
}
}
从上面的例子中,我得到一个结论,finalize()中的打印语句没有每次都被打印,说明并非每次都会调用finalize()方法。
这也验证了我在thinking in java中看到的那句话:
记住,无论是”垃圾回收“还是”终结“,都不保证一定会发生,如果Java虚拟机(JVM)并未面临内存耗尽的情形,它是不会浪费时间去执行垃圾回收以恢复内存的(finalize方法是在垃圾回收动作之前执行)。
最终得到书中的三句话结论:
1.对象可能不被垃圾回收。
2.垃圾回收并不等于”析构“。
3.垃圾回收只与内存有关。