举例讲解Java中final关键字的用法
1.finalvariable
finalvariable就是一个常量,一旦被初始化就不可以被改变。
classTest1{ finaldoublePI=3.14;//常量的名称最好大写 publicTest1(){ PI=3.14; } voidtest(){ System.out.println("PIis:"+PI); } publicstaticvoidmain(String[]args){ Test1t=newTest1(); t.test(); } }
输出:
PIis:3.14
(1)Blankfinalvariable
在声明时未初始化的finalvariable被称作blankfinalvariable,blankfinalvariable必须在构造函数中被初始化,否则会抛出编译错误。
classTest1{ finaldoublePI; Test1(){ PI=3.14;//在构造函数中初始化 } voidtest(){ System.out.println("PIis:"+PI); } publicstaticvoidmain(String[]args){ Test1t=newTest1(); t.test(); } }
输出:
PIis:3.14
(2)Uninitializedstaticfinalvariable
在声明阶段未初始化的staticfinalvariable只能在静态代码块中被初始化
classTest1{ staticfinaldoublePI; static{ PI=3.14; } voidtest(){ System.out.println("PIis:"+PI); } publicstaticvoidmain(String[]args){ Test1t=newTest1(); t.test(); } }
输出:
PIis:3.14
2.finalmethod
finalmethod不能被覆盖。也就是说子类可以调用父类的fianlmethod,但是不能覆盖它。
classTest{ staticfinaldoublePI=3.14; finalvoidtest(){ System.out.println("PIis:"+PI); } } classTest1extendsTest{ publicstaticvoidmain(String[]args){ Test1t=newTest1(); t.test(); } }
输出:
PIis:3.14
3.finalclass
finalcalss不能被继承
finalclassTest1{ staticfinaldoublePI=3.14; finalvoidtest(){ System.out.println("PIis:"+PI); } publicstaticvoidmain(String[]args){ Test1t=newTest1(); t.test(); } }
输出:
PIis:3.14
PS:java.lang.String类为什么设计成final的?
首先,先得清楚final这个关键字。
final的出现就是为了为了不想改变,而不想改变的理由有两点:设计或者效率。final修饰的类是不被能继承的,所以final修饰的类是不能被篡改的。
了解了这一点,我们再看看问题:
(1)从设计上讲,
A、确保它们不会在子类中改变语义。String类是final类,这意味着不允许任何人定义String的子类。换言之,如果有一个String的引用,它引用的一定是一个String对象,而不可能是其他类的对象。
B、String一旦被创建是不能被修改的,因为java设计者将String为可以共享的,下面这段是源码中的注释:
(2)从效率上讲:
A、设计成final,JVM才不用对相关方法在虚函数表中查询,而直接定位到String类的相关方法上,提高了执行效率。
B、Java设计者认为共享带来的效率更高。
总而言之,就是要保证java.lang.String引用引用的对象一定是java.lang.String的对象,而不是引用它的子孙类,这样才能保证它的效率和安全。