Java中的final示例

时间:2020-01-09 10:34:51  来源:igfitidea点击:

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来限制它也是一个矛盾。