Java面试篇之final

来源:互联网 发布:thinkphp5防止sql注入 编辑:程序博客网 时间:2024/06/10 08:34
final是java面试中最常被问到的问题,不管是面试还是笔试都经常会出现此类问题。还是经常会出现问题,就仔细的讲解一下final。Java的关键字final的含义存在着细微的区别,但通常它指的是“这是无法改变的”不想做改变可能出于两种理由:设计或者效率。可能使用到final的三种情况:变量、方法和类。(一)final 变量final关键字声明的变量被认为是常量,任何在程序中试图改变常量值的操作,都会导致编译时错误。对于基本类型,final使数值恒定不变,而用于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象,然而对象其自身却是可以被修改的。下面的示例示范了final域的情况。

import java.util.Random;

class Value {
int i;

public Value(int i) {    this.i = 1;}

}

public class FinalData {
private static Random rand = new Random(47);
private String id;

public FinalData(String id) {    this.id = id;} // Can be compile-time constantsprivate final int valueOne = 9;private static final int VALUE_TWO = 99; // Typical public constantpublic static final int VALUE_THREE = 39; // cannot be compile-time                                            // constantsprivate final int i4 = rand.nextInt(20);static final int INT_5 = rand.nextInt(20);private Value v1 = new Value(11);private final Value v2 = new Value(22);private static final Value VAL_3 = new Value(33);// Arraysprivate final int[] a = { 1, 2, 3, 4, 5, 6 };public String toString() {    return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;}public static void main(String[] args) {    FinalData fd1 = new FinalData("fd1");    // !fd1.valueOne++ ;    // Error:can't change value    fd1.v2.i++;// object isn't constant!    fd1.v1 = new Value(9);    // ok ---not final    for (int i = 0; i < fd1.a.length; i++) {        fd1.a[i]++; // object isn't constant        // ! fd1.v2 = new value(0); // Error can't        // ! fd1.VAL_3 = new Value(1); //change reference        // ! fd1.a = new int[3];    }    System.out.println(fd1);    System.out.println("Creating new FianlData");    FinalData fd2 = new FinalData("fd2");    System.out.println(fd1);    System.out.println(fd2);}

}

运行结果:
fd1: i4 = 15, INT_5 = 18
Creating new FianlData
fd1: i4 = 15, INT_5 = 18
fd2: i4 = 13, INT_5 = 18

由于valueOne和VAL_TWO 都是带有编译时数值的final基本类型,所以他们两者均可以用做编译期常量,并没有重大区别。VAL_THREE是一种更加典型的对常量进行定义的方式:定义为public则可以被用于包之外,定义为static则强调只有一份,定义为final则说明他是一个常量。在fd1 和fd2中,i4的值是唯一的,但INT_5的值是不可以通过创建第二个FinalData对象而加以改变的,这是因为它是static的,在装载时已经被初始化,而不是每次创建新对象时都初始化。
(1)final变量不需要在声明时初始化,程序也可以在声明之后的其他地方初始化final变量。不过这样的初始化必须只执行一次,并且在使用final之前必须初始化。声明时未初始化的final变量叫空缺final变量。
(2) Java允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改参数引用所指向的对象。
class Gizmo {
public void spin() {
}
}

public class FinalArgument {
void with(final Gizmo g) {
// ! g = new Gizmo(); //Illeagl — g is final
}

void without(Gizmo g) {    g = new Gizmo(); // ok g not final    g.spin();}// void f(final int i){i++;} //can't changeint g(final int i) {    return i + 1;}public static void main(String[] args) {    FinalArgument bf = new FinalArgument();    bf.without(null);    bf.with(null);}

}
(二) final方法
使用final方法是把方法锁定,以防任何继承类修改他的含义,确保在继承中使方法行为保持不变,并不会被覆盖。final方法不可以在子类中被重写。
类中所有的private方法都是隐式地指定为是final的。
(三) final类
当将某个类的整体定义为final时,就表明该类不能被继承。该类不需要做任何变动。

0 0
原创粉丝点击