Java final
关键字
原文:https://www.studytonight.com/java-examples/java-final-keyword
final 关键字用于对 Java 中的变量、方法或类进行一些限制。如果一个实体被标记为最终的,那么我们将来就不能改变它的属性。它为不同的实体服务于不同的目的。
在本教程中,我们将学习如何在 Java 中使用 final 关键字。
最终变量
- 如果一个变量被标记为最终变量,那么我们不能给它重新分配一个值。
- 变量将始终具有与初始化时相同的值。
- 如果我们试图进行任何修改,我们将会得到一个编译错误。
- 最终变量用于在程序中定义一个常量值,在程序执行过程中不应改变。
public class Demo
{
public static void main(String[] args)
{
final int num = 10;
num = 500;//Compilation error
}
}
线程“main”Java . lang . error:未解决的编译问题: 最终的局部变量 num 无法赋值。它必须是空白的,并且不能在 Demo.main(Demo.java:6)使用复合赋值
如果一个最终变量已经声明但没有初始化,那么它被称为空白最终变量。
静态字段也可以成为最终字段。它们必须在声明时或在静态块中初始化。类常量总是大写的。下划线用于分隔多个单词。
final static double PI = 3.1415;//Declaring and Initializing a final static variable
final static int BOILING_POINT;//Declaring
static { BOILING_POINT = 100; }//Initializing in Static block
最终参考变量
- 就像最终的基元变量一样,最终引用变量在初始化后不能被重新分配。
- 但是,我们可以更改被引用对象的属性或字段。
例如,在下面的代码中,我们已经创建了最终的学生类引用变量。我们不能使引用变量指向一个新对象。
class Student
{
String name;
Student(String s){
this.name= s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Demo
{
public static void main(String[] args)
{
final Student student = new Student("Justin");
student = new Student("Jessica");//Error because of reassignment
}
}
线程“main”Java . lang . error:未解决的编译问题: 最终的局部变量 student 无法赋值。它必须是空白的,并且不能在 Demo.main(Demo.java:23)使用复合赋值
但是,我们可以更改对象的名称字段。
public class Demo
{
public static void main(String[] args)
{
final Student s = new Student("Justin");
s.setName("Justin Greene");//Modifying final object properties is allowed
System.out.print("Name of Student: " + s.getName());
}
}
学生姓名:贾斯汀·格林
请注意,上述情况也适用于数组,因为数组也作为对象存储。下面的代码演示了这一点。
final int[] intArr = {1, 2, 3};
intArr = new int[5]; //Error as reassignment is not allowed
intArr[1] = 10; //Allowed
最终参数或参数
我们不能修改方法体内的一个最终参数。我们会得到一个编译错误。
public class Demo
{
public static void someMethod(final int num)
{
num = 10;//Error
//...
}
public static void main(String[] args)
{
someMethod(10);
}
}
线程“main”Java . lang . error:未解决的编译问题: 最终的局部变量 num 无法赋值。在 Demo.someMethod(Demo.java:5)和 Demo.main(Demo.java:10)中,它必须为空,并且不使用复合赋值
期末班
- 如果一个类被标记为最终类,那么它不能被任何其他类继承。
- 很多核心 Java 库都包含最终类。像整数或双精度这样的包装类是最终的。
String
类也被声明为最终类。这样做是为了避免继承,以保持类的行为可预测。 - final 关键字也用于创建不可变的类。
- 请注意,使类成为最终类不允许任何其他开发人员扩展或添加特性。我们将失去该类的可扩展性和可继承性。
下面的代码显示了最后一个类,如果 ClassB 试图扩展 ClassA,我们将得到一个编译错误。
final class ClassA{
int a;
ClassA(int x){
this.a = x;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
class ClassB extends ClassA//Error
{
//...
}
请注意,使类成为最终类不会改变类成员的可变性。我们仍然可以改变它们。
final class ClassA{
int a;
ClassA(int x){
this.a = x;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
public class Demo
{
public static void main(String[] args)
{
ClassA classA = new ClassA(10);
System.out.println("Before: " + classA.getA());
classA.setA(15);//Allowed
System.out.println("After: " + classA.getA());
}
}
10 点前 15 点后
最终方法
- 我们也可以将方法声明为 final。最终方法不能被覆盖。
- 许多核心 java 库使用最终方法。像 getClass()、notifyAll()、wait()等方法。在对象类中被定义为最终的。
- 当我们只想限制类方法的覆盖时,Final 方法是 final 类的一个很好的替代方法。
- 尽管每个 Java 类都扩展了 Object 类,但是没有其他类可以覆盖上面提到的最终方法。这样做是为了确保对象的行为一致。
例如,在下面的代码中,子类不能覆盖最终的 printA()方法。
class ClassA{
int a;
ClassA(){
this.a = 100;
}
final void printA()
{
System.out.print("Class A or a Subclass of A");
}
}
class ClassB extends ClassA
{
int b;
ClassB(){
super.a = 150;
this.b = 200;
}
@Override
void printA()//Error
{
System.out.print("Class B");
}
}
然而,在上面的代码中,最终的方法是由 ClassB 继承的。我们可以在 ClassB 的对象上使用 printA()方法。
class ClassA{
int a;
ClassA(){
this.a = 100;
}
final void printA()
{
System.out.print("Class A or a Subclass of A");
}
}
class ClassB extends ClassA
{
int b;
ClassB(){
super.a = 150;
this.b = 200;
}
}
public class Demo
{
public static void main(String[] args)
{
ClassB classB = new ClassB();
classB.printA();
}
}
甲类或甲亚类
摘要
final 关键字可以应用于变量、方法和类。我们不能修改或重新分配最终变量的值。最终方法不能在任何子类中被覆盖。最终类不能有任何子类。在本教程中,我们学习了如何使用 final 关键字对 Java 中的变量、方法和类进行某些限制。