Java中的final关键字和static关键字

目录

1、final 关键字

(1)final 修饰变量、方法和类

(2)final 修饰的集合和不可变集合

2、static 关键字

(1)静态字段

(2)静态方法


        这两个关键字编写代码时会经常用,正确的使用这些关键字,可以形成良好的编程习惯,保护好代码的封装性。

1、final 关键字

        在Java中,利用关键字final指示常量,习惯上,常量名使用全大写。

        关键字final表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。如果将实例字段定义为final,那么这样的字段必须在构造对象时初始化。也就是说,必须确保在每一个构造器执行之后,这个字段的值已经设置,开且以后不能再修改这个字段。

public class Test {
    //私有成员变量:此字段被构造函数赋值后不能再更改
    private final Integer traversalDepth;
    //构造函数
    public Test(Integer traversalDepth) {
        this.traversalDepth = traversalDepth;
    }
}

        在Java中,经常希望某个常量可以在一个类的多个方法中使用,通常将这些常量称为类常量(class constant)。可以使用关键字static final设置一个类常量。如果一个常量被声明为public,那么其他类的方法也可以使用这个常量。//一般情况下为保护封装性,都应该使内部成员变量为私有属性

(1)final 修饰变量、方法和类

        对变量和基本数据类型使用 final:final 表示该变量或基本数据类型只能被赋值一次。一旦赋值后,就不能再改变其值。

        对于引用类型final 保证引用不会改变,但对象本身可以被修改

public class Test {
    final int y;
    final Integer x;
    final List list; //仍然可以往集合中添加元素

    public Test(int y, Integer x, List list) {
        this.y = y;
        this.x = x;
        this.list = list;
    }
}

        对方法使用 final:当方法被声明为 final 时,子类无法重写或覆盖该方法。

        对类使用 final:当类被声明为 final 时,该类不能被继承,即不能有子类。

        final 关键字提供了一种限制或保护代码的方式,确保一些关键的变量、方法或类不被改变或继承。这种特性在编写安全性高、稳定性强的代码时非常有用。

(2)final 修饰的集合和不可变集合

        在 Java 中,使用 final 修饰集合时,意味着该集合的引用不可变,也就是说,这个引用在初始化后不能再指向其他对象。但是,这并不意味着集合本身不可变或不能被修改

import java.util.ArrayList;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        final List list = new ArrayList<>();
        // 可以添加元素,因为集合本身并未被声明为不可变
        list.add("A");
        // 这是合法的,因为没有改变集合引用的指向,仅修改了集合本身的内容
        list.add("B");
        System.out.println("add element to list. list content:" + list);
        list.remove("A");
        System.out.println("remove element from list. list content:" + list);
    }
}

//输出:
add element to list. list content:[A, B]
remove element from list. list content:[B]

        如果你需要创建一个不可变的集合,可以考虑使用 Collections.unmodifiableList()Collections.unmodifiableSet()、Collections.unmodifiableMap() 等方法创建不可变视图,这样的集合视图将不能被修改。例如:

public class Test {
    public static void main(String[] args) {
        List originalList = new ArrayList<>();
        originalList.add("A");
        originalList.add("B");

        List unmodifiableList = Collections.unmodifiableList(originalList);

        //下面的操作会抛出 UnsupportedOperationException 异常
        unmodifiableList.add("c");// 试图添加元素到不可变集合中
    }
}

//输出:
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableCollection.add(Collections.java:1057)
	at test001.Test.main(Test.java:19)

2、static 关键字

(1)静态字段

        如果将一个字段定义为static,那么每个类只有一个这样的字段(类级别的字段。而对于非静态的实例字段,每个对象都有自己的一个副本。例如,假设需要给每一个员工赋予唯一的标识码。 如果将一个字段定义为静态,每个类只有一个这样的字段。而对于非静态的实例字段,每个对象都有自己的一个副本。//static -> 所有类的实例共享一个字段,不会有额外的副本,配上 final 就可成为全局常量

public class Employee {
    private static int globalId;  //属于类,所有实例共享
    private int employeeId;       //每个实例都有一个副本
}

        现在,每一个 Employee 对象都有一个自己的 employeeId 字段,但这个类的所有实例将共享一个 globalId 字段。即使没有 Employee 对象,静态字段 globalId 也存在。它属于类,而不属于任何单个的对象//属于类而不属于实例,所以不需要创建类对象即可调用 static 修饰的 public 成员变量。所以 static 修饰的变量会一直存在于内存,不会随着实例的回收而回收。

(2)静态方法

        类中的静态方法可以直接通过类名调用,而不需要创建类的实例。静态方法通常用于工具类辅助函数不依赖于特定实例的操作。

       static 关键字用于创建与类相关联而不是实例相关联的成员,它们可以通过类名直接访问而无需创建类的实例。

        static 关键字会涉及到类加载对象创建的相关知识点,有关类加载和对象创建可以点击这篇文章:《JAVA对象的创建、内存布局和访问》。

你可能感兴趣的:(Java,final,static,java)