第一 final修饰类
Final修饰的类没有子类,因为它不能被继承,例如java.lang.String类。Final类的所有方法都是final方法。
注意:final不能跟abstract关键字连用,因为重现的类或者方法必须被继承和覆盖才有意义。
第二 final修饰方法
Final方法可以被子类继承,但是不能被子类重写。有人说,父类的private方法是final方法,不过我不这么认为。因为,父类的private方法可以被子类继承,也能被子类覆盖。
第三 final修饰属性
Final属性属于常量,只能被初始化一次,之后不能改变。初始化的方式有两种:
1在声明时初始化
class Test{
final int age = 1;
}
2在构造方法中初始化
class Test{
final int age;
Father(){
age = 1;
}
}
如果final修饰的是个引用变量,如StringBuffer,可以通过调用对象的方法、设置属性等改变其值。但是引用变量本身不能变。示例如下:
//测试类
class Test{
public final StringBuffer sb = new StringBuffer("这是第一个字符串");
public String appendString(String str){
return this.sb.append(str).toString();
}
}
//演示类
class Demo{
public void mytest(){
Test t = new Test();
//错误,因为它对属性sb又一次赋值了
t.sb = "赋值为新字符串";
//正确,以为它并没有改变sb的引用地址
t.sb.append("添加点东西");
//正确,理由同上
t.appendString("又添了一点东西");
}
}
第四 final修饰局部变量
Final局部变量,例如,在一个函数中声明的一个局部变量,JVM会在程序的栈内存中为该变量开辟空间。而堆内存是由GC(垃圾回收器)管理的,所以当函数结束时,该变量依然存在,可以被其他线程或程序段使用,不至于出现空指针异常。这个用法在多线程、定时器和内部类中较为常见。例如:
import java.util.Timer;
import java.util.TimerTask;
public class FinalTest {
public static void test(){
final Timer timer = new Timer();
final int count = 1;
timer.schedule(new TimerTask(){
@Override
public void run(){
System.out.println("2,test方法,输出count=="+count);
//....
//....
//这一句使用了timer变量
timer.cancel();
}
},1000,2000);
}
public static void main(String[] args) {
FinalTest.test();
System.out.println("1,这句话应该在test方法之后运行");
}
}
运行结果是:
1,这句话应该在test方法之后运行
2,test方法,输出count==1
第五 final修饰方法参数
Final参数跟final属性差不多,都是不能更改其值。但是如果参数是引用变量的话可以设置其属性和调用其方法。