Java中的final修饰符,用途演示以及作用深刻理解

final在Java中的含义 final在Java中是完结器,表示不可改变的最终形态。final应用于类、方法、和变量时的意义时不同的,但本质是一样的。 注意事...

final在Java中的含义

final在Java中是完结器,表示不可改变的最终形态。final应用于类、方法、和变量时的意义时不同的,但本质是一样的。

注意事项

1.final修饰变量表示变量的值不可改变,被final修饰过的变量就是常量。2.final修饰方法表示此方法不可以被重写。3.final修饰类表示此类不能被继承。

下面一一介绍final的作用。

1.final修饰变量(基本变量、引用变量)2.final修饰方法3.final修饰类

1.final修饰变量

(1.)final修饰基本变量

final修饰变量,那么此变量即使常量,只能赋值一次,但是final修饰局部变量和成员变量却有所不同。

1.final修饰的局部变量必须在使用之前赋值一次才可以被使用。2.final修饰的成员变量在声明时没有赋值的叫做“空白final变量” 。空白final变量必须在构造方法或者静态代码块当中初始化。

注意:final修饰的变量不能被赋值这种说法是错误的,严格来说,final修饰的变量不可改变,一旦获得了初始值,该final变量的值就不能被重新赋值。

代码演示:

public class FinalTest {

// 静态常量

final static int a = 12; // 直接赋值

final static int b; // 空白final变量

// 静态代码块

static {

b = 20;

}

// 实例常量

final int c = 30; // 直接赋值

final int d; // 空白final变量

// 构造方法

FinalTest() {

d = 33;

// d = 22; // 第二次赋值,编译时会报错

}

void others() {

final int e;

e = 100; // 只能赋值一次

System.out.println(e);

final int f = 111; // 声明的同时赋值

}

}

注意上方代码:

被static修饰过的空白final变量必须在静态代码块当中赋值。没有被static修饰过的空白dinal变量必须在构造方法中进行赋值。

(2.)final修饰引用类型变量

当使用final修饰一个基本类型变量时,不能对基本类型变量重新赋值,修饰过后就是不能改变。但是对于引用类型变量来说,它保存的仅仅是一个引用,final只是保证这个引用类型变量所引用的内存地址不会发生改变,如果引用同一个对象,那么这个对象完全可以发生改变。 换个理解方式,就是说final保证的是内存地址的指针指向不会改变。

代码演示和讲解上述和意思:

public class Person {

private int age;

// 无参构造器

public Person() {

}

// 有参构造器

public Person(int age) {

this.age = age;

}

// 由于age变量私有化,所以通过setter和getter使得子类可以进行方法age变量

public void setAge(int i) {

i = age;

}

public int getAge() {

return age;

}

}

public class FinalReferenceTest {

public static void main(String[] args) {

// 使用final修饰一个引用类型的数组

final int[] iArr = { 5, 6, 12, 9 };

System.out.println(Arrays.toString(iArr));

// 对数组元素进行排序

Arrays.sort(iArr);

System.out.println(Arrays.toString(iArr));

// 对数组元素进行赋值,不会报错

iArr[2] = -8;

System.out.println(Arrays.toString(iArr));

// 如果对iArr数组重新进行赋值,则是错误的

// iArr = null;

// 使用final修饰对象

final Person p = new Person(45);

// 改变Person对象的age实例变量,不会报错

p.setAge(23);

System.out.println(p.getAge());

// 如果对p重新进行赋值,则是错误的,例如:

// p = null;

}

}

对于引用类型变量来说,final保证的只是这个引用类型变量所引用的地址不会改变,也就是说final保证的是这个对象,并不是真正的“内容”。

2.final修饰方法

final修饰的方法不可以被重写,如果在继承当中不希望子类继承父类的某个方法,则可以使用final修饰父类中的方法。如果子类试图重写该方法,将会引发编译错误。

注意:

如果父类当中有一个private修饰的私有方法,子类中再定义一个和父类中私有方法相同方法名、相同参数列表、相同返回值类型的私有方法,不算是方法重写,而是定义一个新的方法。因此,即使使用final修饰一个private访问权限的方法,依然可以在其子类中定义与该方法具有相同方法名、相同参数列表、相同返回值类型的方法。

代码演示:

public class FinalPrivateMethod {

final void method1() {

}

private final void method2() {

}

}

public class Zi extends FinalPrivateMethod{

// 父类中的method1方法被final修饰,子类重写会发生编译报错

// public void method1() {

//

// }

// 父类中的method2方法访问权限时private,子类再次定义method2方法

// 不算是方法重写,而是新定义一个方法

public void method2() {

}

}

上述的父类和子类1虽然有着相同的test方法,但是子类不算是重写父类的test方法,即使父类的test方法使用了final修饰,子类依旧可以定义test方法。

final修饰的方法只是不可以被重写,但是可以重载! 因此像下面这样写也是没有问题的:

public class FinalOverload {

// final 修饰的方法只是不能被重写,完全可以被重载

public final void test(){}

public final void test(String arg){}

}

3.final修饰类

被final修饰的类是不可以被继承的。

但凡被final修饰过的类不可以被任何其它的类所继承,无需代码演示了,因为肯定会发生编译报错。

final修饰符的使用总结

1.final修饰变量

final修饰过的变量一旦初始化则不可改变,这里的不可改变是指对基本类型变量来说是它的值不可以改变,而对对象引用类型变量来说是它的引用不可再变。

注意变量初始化的位置:(上方有代码演示)

1.如果该变量是一个static修饰过的静态变量,则既可以在静态代码块中赋值,也可以在构造方法中赋值,或者直接在定义的时候就赋值。2.如果该变量是一个没有用static修饰过的变量,则既可以直接在定义的时候进行初始化,也可以在构造方法中进行初始化赋值,但是不可以在静态代码块当中进行初始化赋值。3.对于引用类型变量来说,final只是能保证该引用类型变量所引用的地址不会发生改变,就是说final保证的是内存地址的“指针指向”不会改变。

2.final修饰方法

1.被final修饰过的方法不可以在子类当中被重写,但是可以被重载。2.注意private修饰符,如果父类中的方法被private修饰,子类再次定义一个同名的方法,不算方法重写,而是重新定义。

3.final修饰类

final修饰过的类表示该类无法被任何其它的类继承,而对于final修饰过的类来说,该类中的成员可以定义其为final,也可以不是final。对于方法而言,即使没有final修饰,自然也算是final方法,也可以明确的给该方法加上一个final修饰符,这显然没有什么意义。