Java static关键字完全指南:用法、原理与实例解析

Java中的static关键字

Java中的static关键字在Java编程中使用得非常广泛。Java的static关键字用于创建类级别的变量和方法。静态变量和方法属于类本身,而不是类的实例。

Java中static关键字的用途

Java的static关键字可以在五种情况下使用。我们在这里将讨论其中四种情况,第五种情况是在Java 8中引入的,并在Java 8接口更改中进行了详细讨论。

1. Java静态变量

我们可以在类级别变量中使用static关键字。静态变量是一个类变量,不属于类的任何对象或实例。由于静态变量在所有对象实例之间是共享的,所以它们不是线程安全的。通常,静态变量与final关键字一起使用,用于定义所有对象都可以使用的公共资源或常量。如果静态变量不是私有的,我们可以使用ClassName.variableName来访问它。

静态变量示例

private static int count;
public static String str;
public static final String DB_USER = "myuser";

2. Java静态方法

与静态变量类似,静态方法属于类而不是类的实例。静态方法只能访问类的静态变量,并且只能调用类的其他静态方法。通常,静态方法是我们想要公开供其他类使用的实用方法,而不需要创建类的实例。例如,Collections类就包含许多静态方法。Java包装类和实用程序类也包含大量静态方法。Java程序的入口点main()方法本身就是一个静态方法。

静态方法示例

// 静态方法示例
public static void setCount(int count) {
    if(count > 0)
        StaticExample.count = count;
}

// 静态实用方法
public static int addInts(int i, int...js){
    int sum = i;
    for(int x : js) sum += x;
    return sum;
}

从Java 8开始,接口中也可以有静态方法。有关更多详细信息,请阅读Java 8接口更改的相关文档。

3. Java静态代码块

Java静态代码块是一组在类被Java类装载器加载到内存时执行的语句。静态块主要用于初始化类的静态变量。在类加载时,通常用来创建静态资源。在静态块中,我们无法访问非静态变量。在一个类中,我们可以有多个静态代码块,尽管这种做法没有太多实际意义。静态代码块的代码在类加载到内存时只执行一次。

静态代码块示例

static {
    // 可以在类加载时初始化资源
    System.out.println("StaticExample静态代码块");
    // 只能访问静态变量和方法
    str = "Test";
    setCount(2);
}

4. Java静态类

我们可以使用static关键字与嵌套类一起使用。需要注意的是,静态关键字不能与顶级类一起使用。静态嵌套类与任何其他顶级类相同,只是为了便于封装而嵌套在另一个类中。如需了解更多信息,可以阅读Java嵌套类相关文档。

Java中static关键字的使用示例

让我们通过一个完整的示例程序来了解Java中static关键字的使用情况。

StaticExample.java

package com.Olivia.misc;

public class StaticExample {

    // 静态代码块
    static {
        // 可以在类加载时初始化资源
        System.out.println("StaticExample静态代码块");
        // 只能访问静态变量和方法
        str = "Test";
        setCount(2);
    }
    
    // 同一类中的多个静态代码块
    static {
        System.out.println("StaticExample静态代码块2");
    }
    
    // 静态变量示例
    private static int count; // 保持私有以通过setter控制其值
    public static String str;
    
    public int getCount() {
        return count;
    }

    // 静态方法示例
    public static void setCount(int count) {
        if(count > 0)
            StaticExample.count = count;
    }
    
    // 静态实用方法
    public static int addInts(int i, int...js){
        int sum = i;
        for(int x : js) sum += x;
        return sum;
    }

    // 静态类示例 - 仅用于包装便利
    public static class MyStaticClass {
        public int count;
    }
}

TestStatic.java

package com.Olivia.misc;

public class TestStatic {

    public static void main(String[] args) {
        StaticExample.setCount(5);
        
        // 非私有静态变量可以通过类名访问
        StaticExample.str = "abc";
        StaticExample se = new StaticExample();
        System.out.println(se.getCount());
        // 类和实例的静态变量是相同的
        System.out.println(StaticExample.str +" 与 "+se.str+" 是相同的");
        System.out.println(StaticExample.str == se.str);
        
        // 静态嵌套类就像普通的顶级类一样
        StaticExample.MyStaticClass myStaticClass = new StaticExample.MyStaticClass();
        myStaticClass.count = 10;
        
        StaticExample.MyStaticClass myStaticClass1 = new StaticExample.MyStaticClass();
        myStaticClass1.count = 20;
        
        System.out.println(myStaticClass.count);
        System.out.println(myStaticClass1.count);
    }
}

程序输出

StaticExample静态代码块
StaticExample静态代码块2
5
abc 与 abc 是相同的
true
10
20

请注意,静态块代码在类加载到内存时首先执行一次。其他输出都很容易理解。

Java静态导入

通常我们使用类引用来访问静态成员,但从Java 1.5开始,我们可以使用Java静态导入来避免使用类引用。下面是一个简单的Java静态导入示例。

A.java

package com.Olivia.test;

public class A {

    public static int MAX = 1000;
    
    public static void foo() {
        System.out.println("foo静态方法");
    }
}

B.java

package com.Olivia.test;

import static com.Olivia.test.A.MAX;
import static com.Olivia.test.A.foo;

public class B {

    public static void main(String args[]) {
        System.out.println(MAX); // 通常写作A.MAX
        foo(); // 通常写作A.foo()
    }
}

请注意导入语句,对于静态导入,我们必须使用import static,后跟类的完全限定的静态成员。如果要导入类的所有静态成员,我们可以使用通配符*,如import static com.Olivia.test.A.*;。当我们频繁使用类的静态变量时,才应该使用静态导入,因为过度使用会对代码可读性产生不利影响。

更新:我最近创建了一个视频来解释Java中的静态关键字,你可以在下面观看它:https://www.youtube.com/watch?v=2e-l1vb\_fwM

bannerAds