介绍
final关键字使用在不同的场景中,final仅仅可以应用到variable,method,class中。
- final variable(创建常量)
- final methods(防止方法重写)
- final classes(防止类继承)
当变量声明为final,它的值不能被修改,是一个常量。必须初始化一个final变量。如果final变量是一个引用,这个变量就不能重新引用到其他对象了,但是通过变量指向的对象的状态是可以改变的,例如可以从final array中添加或者删除元素。最好声明final变量为大写,使用下划线连接单词。
例如:
// a final variable
final int THRESHOLD = 5;
// a blank final variable
final int THRESHOLD;
// a final static variable PI
static final double PI = 3.141592653589793;
// a blank final static variable
static final double PI;
初始化final变量
我们必须初始化final变量,否则编译器将会抛出异常。final变量仅仅可以初始化一次。有三种方法初始化final变量
- 当声明final变量时,可以初始化final变量,这种方法最普遍。当声明时,并没有初始化,就叫做空白final变量,需要下面两种方法进行初始化
- 一个空白final变量可以在instance-initializer block或者构造函数中初始化,如果有多个构造函数,必须在每个构造函数中初始化,否则编译器会抛出错误
- 一个空白final static变量可以在static块中初始化
class Gfg
{
// a final variable
// direct initialize
final int THRESHOLD = 5;
// a blank final variable
final int CAPACITY;
// another blank final variable
final int MINIMUM;
// a final static variable PI
// direct initialize
static final double PI = 3.141592653589793;
// a blank final static variable
static final double EULERCONSTANT;
// instance initializer block for
// initializing CAPACITY
{
CAPACITY = 25;
}
// static initializer block for
// initializing EULERCONSTANT
static{
EULERCONSTANT = 2.3;
}
// constructor for initializing MINIMUM
// Note that if there are more than one
// constructor, you must initialize MINIMUM
// in them also
public GFG()
{
MINIMUM = -1;
}
}
什么时候使用final变量
final变量与普通变量仅有的不同是:普通变量可以重新赋予值,但是final变量只要一赋予,就不能修改。因此final变量仅仅应用在程序执行过程中不需要修改的变量上。
应用final变量
当final变量引用一个对象,那么这个final变量叫做引用final变量,例如
final StringBuffer sb;
final变量不能重新分配,但是被引用final变量指向的对象的内部状态可以修改,这并不是重新分配,可以下面例子说明:
class Gfg
{
public static void main(String[] args)
{
// a final reference variable sb
final StringBuilder sb = new StringBuilder("Hello");
System.out.println(sb);
// changing internal state of object
// reference by final reference variable sb
sb.append("World");
System.out.println(sb);
}
}
输出为:
Hello
HelloWorld
因为final变量不能被重新分配,所以下面的代码会抛出异常
class Gfg
{
static final int CAPACITY = 4;
public static void main(String args[])
{
// re-assigning final variable
// will throw compile-time error
CAPACITY = 5;
}
}
Compiler Error: cannot assign a value to final variable CAPACITY
当final变量在method、constructor,block中创建时,叫做本地final变量,必须在创建时就初始化。
class Gfg
{
public static void main(String args[])
{
// local final variable
final int i;
i = 20;
System.out.println(i);
}
}
输出
20
Java中的final变量可以在声明之后赋予值,但是仅仅一次 。
final可以与for循环结合使用,例如:
class Gfg
{
public static void main(String[] args)
{
int arr[] = {1, 2, 3};
// final with for-each statement
// legal statement
for (final int i : arr)
System.out.print(i + " ");
}
}
输出
1 2 3
因为每次迭代时,会重新声明i变量。
final类
一个final class不能被继承,有下面两种使用场景:
防止继承,例如,像Integer,Float的Wrappter classes都是final classes。我们不能继承他们。
final class A
{
// methods and fields
}
// The following class is illegal.
class B extends A
{
// COMPILE-ERROR! Can't subclass A
}
另一种就是创建一个不变的class,像预定义的String class。如果没有final,并不能控制class不可变。
final方法
一个final方法不能重写,Object类的许多方法就是final方法。如果我们想要派生的classes实现相同的方法,那么就要声明为final方法。
class A
{
final void m1()
{
System.out.println("This is a final method.");
}
}
class B extends A
{
void m1()
{
// COMPILE-ERROR! Can't override.
System.out.println("Illegal!");
}
}