Java新手必看:final关键字的正确使用技巧,让你避免常见错误!

Java新手必看:final关键字的正确使用技巧,让你避免常见错误!_第1张图片

在Java中,final关键字表示“最终的”或“不可变的”,用于标记变量、方法和类。它有助于确保数据的安全性、API设计的稳定、性能优化以及支持设计模式。当变量被标记为final时,其值不可更改,保障了数据的完整性和安全性。在API或库设计中,使用final可防止意外或恶意修改。同时,final变量在编译时可进行优化,提高性能。声明类为final可防止继承,确保行为不被修改。方法声明为final则子类不能重写,保持一致性。此外,final还能明确开发者意图,提高代码可读性和可维护性。

用final来修饰类

如果想要防止其他类继承父类,可以使用final关键字来修饰这个类,如下代码:

public final class MyClass {  
    // 类的成员变量和方法  
      
    public void myMethod() {  
        // 方法实现  
    }  
      
    // 注意:由于MyClass被声明为final,因此它不能被继承。  
    // 下面这种尝试继承MyClass的做法将会导致编译错误:  
    /*  
    public class AnotherClass extends MyClass {  
        // 这里的代码将不会编译通过,因为MyClass是final的。  
    }  
    */  
}

在这个示例中,MyClass被声明为final,这意味着没有任何类可以继承它,如果尝试创建一个新类并继承MyClass,编译器将会报错,这种方法通常用于确保类的行为不会被修改,或者当类被设计为独立实体而不应作为继承体系的一部分时。

用final修饰方法

当想要防止子类重写父类中的某个方法时,可以在父类的方法上使用final关键字,这样做可以确保子类不会改变这个方法的行为,如下代码:

public class ParentClass {  
  
    // final方法,子类不能重写这个方法  
    public final void showFinal() {  
        System.out.println("This is a final method.");  
    }  
  
    // 非final方法,子类可以重写这个方法  
    public void showNonFinal() {  
        System.out.println("This is a non-final method.");  
    }  
}  
  
// 子类尝试重写父类的final方法将会导致编译错误  
class ChildClass extends ParentClass {  
  
    // 下面的方法是错误的,因为showFinal()在父类中是final的,不能被重写  
    /*  
    @Override  
    public void showFinal() {  // 这行会导致编译错误  
        System.out.println("Trying to override final method.");  
    }  
    */  
  
    // 子类可以正常重写父类的非final方法  
    @Override  
    public void showNonFinal() {  
        System.out.println("ChildClass overrides non-final method.");  
    }  
}  
  
public class FinalMethodDemo {  
    public static void main(String[] args) {  
        ParentClass parent = new ParentClass();  
        parent.showFinal();      // 输出: This is a final method.  
        parent.showNonFinal();   // 输出: This is a non-final method.  
          
        ChildClass child = new ChildClass();  
        // child.showFinal();      // 如果尝试调用一个被重写的final方法,这里会报错,但实际上不会尝试这么做,因为不能重写final方法  
        child.showNonFinal();     // 输出: ChildClass overrides non-final method.  
    }  
}

在上面的代码中,ParentClass有一个final方法showFinal()和一个非final方法showNonFinal(),在ChildClass中,我们尝试重写showFinal()方法(这部分代码是被注释掉的,因为它会导致编译错误),但成功重写了showNonFinal()方法,在FinalMethodDemo类的main方法中,我们创建了ParentClassChildClass的实例,并调用了这两个方法,以展示final方法不能被重写,而非final方法可以被重写。

用final修饰字段

在Java中,final关键字也可以用于类的字段(成员变量),当一个字段被声明为final时,它必须在声明时被初始化或者在构造器中被初始化,并且之后它的值就不能再被修改了,如下代码:

public class Person {  
  
    // final字段,必须在声明时或构造器中初始化,之后不能更改  
    private final String name;  
    private final int age;  
  
    // 构造器,用于初始化final字段  
    public Person(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
  
    // getter方法,用于获取final字段的值  
    public String getName() {  
        return name;  
    }  
  
    public int getAge() {  
        return age;  
    }  
  
    // 注意:以下尝试修改final字段的方法将会导致编译错误  
    /*  
    public void setName(String newName) {  
        this.name = newName; // 编译错误:不能赋值给final字段name  
    }  
  
    public void setAge(int newAge) {  
        this.age = newAge; // 编译错误:不能赋值给final字段age  
    }  
    */  
}  
  
public class FinalFieldDemo {  
    public static void main(String[] args) {  
        // 创建一个Person对象,final字段在构造器中被初始化  
        Person person = new Person("Alice", 30);  
          
        // 输出final字段的值  
        System.out.println("Name: " + person.getName()); // 输出: Name: Alice  
        System.out.println("Age: " + person.getAge());   // 输出: Age: 30  
          
        // 尝试修改final字段(实际上不会这么做,因为知道这是不可能的)  
        // person.setName("Bob"); // 这行代码不会存在,因为setName方法不存在且name是final的  
        // person.setAge(35);     // 同上,setAge方法不存在且age是final的  
    }  
}

在这个示例中,Person类有两个final字段:nameage,这两个字段在构造器中被初始化,并且由于它们是final的,因此没有提供setter方法来修改它们的值,在FinalFieldDemo类的main方法中,我们创建了一个Person对象并输出了其nameage字段的值,注释掉的代码部分展示了尝试修改final字段将会导致的编译错误。

核心总结

在Java编程中,final关键字是一把双刃剑,既强大又需审慎使用。

它的优点显而易见,它提供了数据的安全保障,一旦定义为final的变量,就如同加上了不可更改的封印,有效防止数据被篡改,同时,final也助力性能优化,编译器对final变量有特殊照顾,能进行更多的优化处理,在代码设计上,final明确表达了开发者的意图,使得代码更易读、更易于维护。

然而,它的缺点也不容忽视,过度使用final可能导致代码丧失灵活性,使得后续的修改和扩展变得困难。在确实需要保障数据不变性或方法行为不被覆盖的场合使用final,同时要注意避免滥用,保持代码的灵活性和可维护性。

你可能感兴趣的:(java,开发语言)