Java中的final示例
Java中的final关键字可以与字段,方法或者类一起使用。在Java中使用final的任何上下文中,它都会以某种方式限制访问。
Final变量–如果某个字段被声明为Final变量,则赋值后就无法更改其值。
Final方法–不能覆盖声明为final的方法。
Final类–声明为final的类不能扩展。
Java中的Final变量
当字段声明为final时,无法对其进行修改,因此使其成为常量。由于Final变量是常量,因此最好以大写形式给出Final变量名称。
由于Final变量的值无法修改,因此Final变量只能初始化一次。初始化可以通过以下方式完成:
我们可以在声明Final变量时对其进行初始化。例如– final int WEEK_OF_DAYS = 7;
我们可以在构造函数,初始值设定块或者静态块中延迟分配以完成此操作(如果字段和final一样也是静态的)。在声明时未初始化的Final变量在Java中称为空白Final变量。
Java Final字段示例
当声明但未初始化时–在这种情况下,我们将收到一个编译时错误,即空白的final字段可能尚未初始化。
在构造函数中初始化final字段
public class FinalDemo { final int DAYS_IN_WEEK; FinalDemo(){ DAYS_IN_WEEK = 7; } public static void main(String[] args) { FinalDemo finalDemo = new FinalDemo(); } }
在初始化程序块中初始化final字段
public class public class FinalDemo { final int DAYS_IN_WEEK; { DAYS_IN_WEEK = 7; } public static void main(String[] args) { FinalDemo finalDemo = new FinalDemo(); } }
在静态块中初始化静态Final字段
public class public class FinalDemo { final static int DAYS_IN_WEEK; static{ DAYS_IN_WEEK = 7; } public static void main(String[] args) { FinalDemo finalDemo = new FinalDemo(); } }
尝试更改Final字段的值–这会导致编译器错误,因为初始化后无法修改Final字段。
方法中的Final变量
在上面的示例中,final字段位于类级别,但是我们也可以在方法中使用final变量。声明局部变量final也具有相同的效果;值不能多次分配给它。
甚至可以在Java中将方法参数声明为final,这样就无法更改参数值。
例如-public void getValue(Finalint量,Finalint年)
Final变量保存对象参考
如果Final变量包含对象引用,则我们可以更改任何对象字段的值,但不能更改Final变量所包含的引用。这是有道理的,因为在对象引用的情况下,变量的值是内存引用,因此在Final值的情况下不能更改。让我们来看一个例子。
Final对象参考Java示例
在这里,我们有一个带有年龄和姓名字段的Employee类。Final变量employee保留对Employee对象的引用。在代码中,我们可以看到可以更改字段值,但是尝试更改引用employee = new Employee();。会导致编译时错误。
class Employee{ int age; String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class FinalDemo { final int DAYS_IN_WEEK = 7; public static void main(String[] args) { // final variable holding object reference final Employee employee = new Employee(); // setting field values employee.setAge(25); employee.setName("Hyman"); System.out.println("Employee Age " + employee.getAge()); // changing field value - That is OK employee.setAge(35); System.out.println("Employee Age " + employee.getAge()); // Can't change the reference employee = new Employee(); // Compiler error } }
Java中的Final方法
我们也可以在Java中将方法声明为final方法,从而使其成为final方法。Final方法不能被覆盖。
如果某个方法在父类中声明为final方法,则子类无法覆盖该方法并更改实现。
如果我们在类中有任何方法被认为具有完整的功能,那么我们可以将其声明为final方法,以便子类使用相同的实现。
Final方法Java示例
在这里我们可以看到尝试覆盖子类中的displayValue()方法会导致编译器错误无法覆盖父级的Final方法
Final方法的性能优势
将方法声明为final可能还会提高代码的性能。在Java中,通常在运行时解决对方法的调用,这称为动态绑定或者后期绑定。
将方法标记为Final方法时,Java编译器会知道该方法无法被覆盖,因此可以在编译时自行解决对该方法的调用。这称为静态或者早期绑定。如果在运行时解决了方法调用,则可以内联该方法,这意味着可以将方法代码放在调用它的位置。这避免了运行时方法调用的开销,从而提高了性能。
Java中的Final类
如果我们在Java中将某个类声明为final类,则该类不能扩展(我们不能从final类继承)。在Java中,将类声明为final可以通过以下方式:
如果我们有一个确定具有所有必需功能的类,并且不应将其子类化以添加任何其他功能,则应在Java中将其声明为final。
需要将一个类标记为final的另一个特别有用的场景是在创建不可变类(如String类)时。
请注意,我们无法在Java中将类声明为final和abstract。由于设计上的抽象类依赖于子类来提供完整的实现,因此通过将类标记为final来限制它也是一个矛盾。