Java 基础17 final 关键字介绍


1. Final介绍

final 中文意思是最后的,最终的。

final可以修饰类、属性、方法和局部变量。

在某些情况下,程序员可能有一下需求,就会使用到final

2. final 修饰类

使用 final 修饰类表示该类不能被继承。也就是说,final 类是最终的、不可改变的类。当一个类被 final 修饰时,它的所有成员方法也被隐式地指定为 final 方法,不能被子类重写。

final 类通常用于设计不可变类或者安全类,以防止子类继承和篡改。它还可以用于提高代码性能,因为编译器在编译时可以对 final 类进行优化。

使用 final 修饰的类不能被继承,但它仍然可以包含其他类所拥有的成员变量和成员方法。同时,final 修饰符还可以用于修饰类中的成员变量和成员方法,表示它们只能被初始化一次或者只能被调用一次。

需要注意的是,final 类并不一定就是最好的选择。使用 final 修饰类会使得该类不能被继承,这可能会限制代码的扩展性和灵活性。因此,在选择是否使用 final 修饰类时,需要根据具体的应用场景来综合考虑。

// 1.当不希望类被继承时,可以使用 final 修饰类,这样他就不能被其他类继承
final class Animal01{}
// 报错,使用 final 修饰的类无法被继承
class Dog01 extends Animal01{} // 报错!!!

3. final 修饰方法

使用 final 修饰方法表示该方法不能被子类重写。当一个方法被 final 修饰时,它不能被子类重写或者覆盖。

final 方法通常用于设计不可变类或者安全类,以防止子类重写某些关键方法。同时,final 方法还可以用于提高代码性能,因为编译器在编译时可以对 final 方法进行优化,从而减少程序的运行开销。

需要注意的是,final 方法只能被子类继承和调用,不能被子类重写。因此,当一个方法被 final 修饰时,应该仔细考虑其对代码的影响,以免影响代码的可维护性和扩展性。

class Animal01{
    // 2. 如果不该希望方法被重写或覆盖可以使用 final 修饰
    public final void say(){

    }
}
class Dog01 extends Animal01{
    // 这时子类无法重写父类的 final 方法
    @Override
    public void say() { //报错,使用 final 修饰的方法无法被重写
        System.out.println("重写父类方法");
    }
}

4. final 修饰属性

使用 final 修饰属性表示该属性只能被赋值一次,赋值后不能再次修改。当一个属性被 final 修饰时,它可以在构造方法中或者属性声明时进行初始化,并且在对象创建后不能再被修改。

final 属性通常用于设计不可变类或者安全类,以保证类的属性不会被篡改。同时,final 属性还可以用于提高代码的可读性和可维护性,因为它们不能被修改,因此可以提供更好的代码清晰度。

需要注意的是,final 属性只能被初始化一次,因此必须在声明时或者构造方法中初始化。如果 final 属性是一个对象类型,则其引用可以被修改,但是其所指向的对象不能被修改。

使用 final 修饰属性可以提高代码的可读性、可维护性和安全性,但是需要注意其在构造方法中的初始化顺序和规范使用。

class Animal01{
    // 3. 如果不该希望属性值被修改,可以使用 final 修饰
    public final int age = 2;
}

public class Final01 {
    public static void main(String[] args) {
        Animal01 animal = new Animal01();
        animal.age = 10; //报错 ,使用 final 修饰的属性无法被修改
    }
}
  1. 当不希望某个局部变量的值被修改时,可以使用final修饰该局部变量
public class Final01 {
    public static void main(String[] args) {
        // 4. 如果不希望局部变量的值被修改时,可以使用final修饰该局部变量量
        final float pi = 3.14f;
        pi = 4.1415; // 报错,使用 final 修饰的局部变量无法被修改
    }
}

5. final 修饰静态属性

使用 final 修饰静态属性表示该属性只能被赋值一次,赋值后不能再次修改。当一个静态属性被 final 修饰时,它可以在静态代码块中或者属性声明时进行初始化,并且在类加载后不能再被修改。

final 静态属性通常用于设计常量,以保证它们的值不会被篡改。同时,final 静态属性还可以用于提高代码的可读性和可维护性,因为它们不能被修改,因此可以提供更好的代码清晰度。

需要注意的是,final 静态属性只能被初始化一次,因此必须在声明时或者静态代码块中初始化。如果 final 静态属性是一个对象类型,则其引用可以被修改,但是其所指向的对象不能被修改。

使用 final 修饰静态属性可以提高代码的可读性、可维护性和安全性,但是需要注意其在静态代码块中的初始化顺序和规范使用。

  • final 修饰情态属性初始化的位置:
  1. 定义时现显式的赋值
  2. 静态代码块中显式的赋值
  3. 注意不能 在构造器中赋值
public class Final03 {
    // 如果 final 修饰的属性时静态的, 则初始化可以在如下两个位置之一
    // 1. 定义时显式的赋值
    final static String FINAL_NAME_ONE = "final.name.1";

    final static String FINAL_NAME_TWO; //

    static {
        // 2. 在代码块中赋值
        FINAL_NAME_TWO = "final.name.2";
    }

    // 注意: 如果 final 修饰的属性时静态的 不能 在构造器中赋值
    final static String FINAL_NAME_THREE;
    public Final03(){
        FINAL_NAME_THREE = "final.name.3";
    }
}

6. final 使用注意事项和细节讨论

  1. final 修饰的属性又叫常量,一般使用 XXX_XXX_XXX来命名

  2. final 修饰的属性在定义时,必须赋予初始值,并且以后不能在修改, 赋值可以在如下三个位置之一(选择一个位置赋初始值即可)

    1. 定义时显式的赋值(优先级最高): 如 public final int a = 10;
    2. 在代码块中赋值(优先级中)
    3. 在构造器中赋值(优先级低)
public class Final02 {
    // 1. final修饰的属性又叫常量,一般使用 XXX_XXX_XXX来命名
    // 2. final 修饰的属性在定义时,必须赋予初始值,并且以后不能在修改
    // 2.1 定义时显式的赋值
    final String FINAL_NAME_ONE = "final.name.1";
    final String FINAL_NAME_TWO; //
    final String FINAL_NAME_THREE; //

    {
        // 2.2 在代码块中赋值
        FINAL_NAME_TWO = "final.name.2";
        //因为在常量在定义时已经赋值了,不能对其值进行修改
        // FINAL_NAME_ONE = "final.name.1";
    }

    public Final02(){
        // 2.3 在构造器中赋值
        FINAL_NAME_THREE = "final.name.3";
    }
}
  1. final类不能被继承,但是可以被实例化,final类中的属性也可以被修改
public class Final04_finalclass {
    public static void main(String[] args) {
        // final 修饰的类可以被实例化
        Animal04 animal = new Animal04();
        // final 修饰的类里的属性也可以被修改
        animal.a = 100;
        System.out.println(animal.a);
    }
}

// 被final 修饰的类不能被继承
// class Dog extends Animal04{ }

final class Animal04{
    int a = 10;
}
  1. 如果类不是final类, 但是含有final方法, 则该方法虽然不能被重写, 但是依然可以被继承
public class Final05_finalclass {
    public static void main(String[] args) {
        Dog05 dog = new Dog05();
        dog.say(); // hello
        Animal05 animal = new Animal05();
        animal.say(); // hello
    }
}

class Dog05 extends Animal05{

    // final修饰的方法不能被重写
//    public void say(){
//        System.out.println("wang!wang~wang~");
//    }
}

class Animal05{
// final 修饰了类中的某个方法,类依然可以被继承, 但是该方法不能被重写
    public final void say(){
        System.out.println("hello");
    }
}
  1. 一般来说, 如果一类是final修饰的类, 那么就没有必要再使用final修饰该类中的方法了
  2. final不能修饰构造方法
  3. final 和 static 往往搭配使用,因为底层编译做了优化处理,不会导致类加载, 所以效率更高
  4. 包装类(Integer、Double、Float)等都是 final 类,String 也是 final 类

文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
 上一篇
Spark Streaming 1. 介绍 Spark Streaming 1. 介绍
1. 介绍Spark Streamingspark streaming 是 spark 核心 api 的扩展,支持可扩展,高吞吐量,实时数据流的容错处理,数据可以从 kafka,flume,Kinesis 或者 TCP socket 中获取
2018-02-24
下一篇 
Java 基础16 static 代码块介绍 Java 基础16 static 代码块介绍
1. 代码块基本介绍代码块又称为初始化块, 属于类中的成员, 即为类的额一部分,类似于方法,将逻辑语句封装在方法体中, 通过 {} 包围起来。 但代码块又和方法不同, 没有方法名,没有返回值, 没有参数,只有方法体,而且不通过对象或类显式调
2018-02-19
  目录