本文共 2595 字,大约阅读时间需要 8 分钟。
final是一个java关键字,一个修饰符,可用于修饰变量,方法,修饰类.
fianl最常见的用法时用来修饰成员变量,成员变量分为静态变量与普通变量.
对于final修饰的变量,不是不能被赋值,是其值不能被改变,可以理解成只能赋一次值.可以在定义时赋值,也可以在定义后在另外赋值,但无论何种方式只能被赋值一次.修饰静态变量时,可以选择以下两种方式赋值:
final static int a = 6;final static int b;static { b = 6;}
修饰普通成员变量时,可以选择以下三种方式赋值:
public class test{ int c = 1; int d; int e; { d = 2; } public test() { e = 3; }}
根据"静态"不能访问"非静态"规则,就是说静态的方法不能访问非静态成员,static初始化块不能初始化非静态成员,普通初始化块也不能初始化静态变量.
但是,有一个"bug"就是java允许通过方法访问final成员,因此…有趣的事情发生了.public class test{ final int a; { System.out.println(a);//这里会报错 printA(); a = 3; printA(); } void printA() { System.out.println(a); } public static void main(String[] args) { new test(); }}
以上这段代码会报错,因为java不允许final成员未初始化前访问.
public class test{ final int a; { //System.out.println(a);//这里会报错 printA(); a = 3; printA(); } void printA() { System.out.println(a); } public static void main(String[] args) { new test(); }}
printA()中只是用方法包装了一下输出函数,居然就通过了编译…有没有兴趣看一下结果?
final修饰局部变量其实也分两种,一种是修饰形参,一种是修饰方法内部的局部变量
没什么好说的…就是形参的值不能改变.
public void f(final int a){ a = 3;//报错.}
修饰局部变量时可以定义时赋值,也可以在定义后在赋值(仅一次).
public void f(){ final int a = 3; final int b; b = 2;}
嗯…这个是一个特别一点的例子,Talk is cheap.上代码.
import java.util.Arrays;public class test{ public static void main(String[] args) { final int[] arr = { 1,2,3}; arr[1] = 5; Arrays.stream(arr).forEach(System.out::print); System.out.println(); final A a = new A(); a.setA(9); System.out.println(a.getA()); }}class A{ private int a = 3; public void setA(int a) { this.a = a; } public int getA() { return a; }}
为什么final数组可以赋值???fianl对象的值被改变了???看看结果:
final修饰的方法不能被重写,当然,不能"配合"private"使用",因为private把方法变成了私有,相当于对子类不可见,子类都不知道父类"还有这玩意",就可以进行所谓的"重写"了.
class A{ private final void f(){ }}class B extends A{ public final void f(){ }//没毛病}
因为B类的f()是属于B类的,不是从A类继承过来的.
final修饰类时表示该类不能被继承.
final class A{ }class B extends A{ }//出错
这是作者的公众号,欢迎关注.
转载地址:http://rwyq.baihongyu.com/