您的位置:首页 > 编程语言 > Java开发

java基础知识——final关键字

2016-06-06 23:21 639 查看
final可以修饰类,方法,变量和参数。

final类

被final修饰的类,就是final类,表示此类不能被继承。如果我们设计的类,想禁止被继承。则可以使用final关键字进行强制指出。这样,如果有人想继承final类,则编译器会给出编译错误。

final class TestFinal{
}

//compile-time error : SubClass cannot inherit from final class
class SubClass extends TestFinal{
}


在java中有很多类都是被设计成final类,表示禁止用户进行扩展。如字符串操作的String,StringBuilder类,装箱类Integer,Long等类。

在java中一个类是不允许同时被abstract和final这两个关键字修饰的。因为final表示类是最终的,是已经完全完成的,不能再被修改和继承的;而abstract表示类是残缺的,是不完整的,就是需要被子类继承和修改的。

final方法

被final修饰的方法,有两个优点。

1. 此方法不允许在子类被重写(Overriding)。

2. 效率。所有的final方法,在运行的时候,都会被内联(inline)优化,即用方法的代码,替换函数调用。

在inline的时候,java不会改变函数调用语义的,比如,对null对象调用方法,无论有没有inline,都会抛出NullPointerException异常。

class Parent{
public final void f1(){
System.out.println("This is parent class,f1 function.");
}
}

class Child extends Parent{
public void f1(){
//compile-time error : Overridden method is final
}
}


private方法和final类内的所有的方法,都是不可能被重写的,所以,默认都是final方法。

final变量

java中变量,大致分为有三种(个人理解,不一定正确)。局部变量(local variable),类成员变量(instance variable),类静态变量(class variable)。这三种变量都是可以被final关键字修饰的。

但这三者却又不太相同。

final修饰的类静态变量(class variable),可以在定义的地方赋值,也可以在静态初始化区进行赋值。

final修饰的类成员变量(instance variable),必须在定义的地方赋值,或者在构造函数结束前进行赋值。

final修饰的局部变量,可以在任何地方进行一次赋值,也可以不赋值。

所有被final修饰的变量,只能被赋值一次。如果final修饰的变量被赋值两次,则会产生编译期错误。

final变量与常量的区别

虽然,final变量,只能被赋值一次。但并不代表final变量的值,不会被改变。如果final变量是一个对象的引用。则final变量表示,则对象引用不能被修改。但仍然可以通过对象的操作,改变对象的内部值。典型的,则是Array对象。

public class FinalTest {
static final String [] strArray = new String[3];

public static void main( String[] args ) {
System.out.print("Old array object:");
for (String str:strArray){
System.out.print(str + "  ");
}
System.out.println();
strArray[0] = "String1";
System.out.print("New array object:");
for (String str:strArray){
System.out.print(str+"  ");
}
}
}


上面代码的输出结果如下:

Old array object:null  null  null
New array object:String1  null  null


从上面的结果,可以看到final变量字符串数组strArray内的字符串的值改变了。这是因为strArray对象没有改变,仍然是一个含三个字符串的数组对象。但数组的字符串引用是可变的。

如果final修饰的变量是内置数据类型(int,double)或者自动装箱类型,或者是String,则此变量是常量。因为此变量的引用和值都是不能改变的。

默认final变量

java中有三类变量是默认就是final变量,是只能被赋值一次的。虽然没有显式添加final关键字修饰,但

1. interface(接口)的静态变量;interface的所有变量都是public static final类型的

2. try-with-resources里定义的局部变量。try-with-resources是java7的新特性,可以自动回收资源。

3. multi-catch clause里定义的异常对象。

下面的代码,演示了,这三种

interface Parent{
String str = "";
}

class Child implements Parent{
public Child(){
//interface的变量都是final
//cannot assign a value to final variable
str = "1";
try {
throw new SQLException();
}catch (SQLException | NullPointerException e ){
//multi-catch clause的变量是final的
//cannot assign a value to final variable
e = new NullPointerException();
}

try (BufferedReader br =
new BufferedReader(new FileReader(""))) {
// try-with-resources里定义的局部变量是final的
// cannot assign a value to final variable
br = new BufferedReader(new FileReader(""));
} catch (IOException e) {
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java final 常量 不可变