static

Published 2026-07-29 08:41 Updated 2026-07-29 08:41 1419 words 8 min read ... Page views

The article systematically introduces the usage scenarios and principles of several core keywords in Java: static members decorated with static belong to the class itself, are shared and initialized when the class is loaded; instances and static initialization blocks are executed in a specific order, which affects the object creation process; The singleton pattern realizes sharing of instances through hungry and lazy styles;abstract is used to define abstract classes and methods. Abstract classes cannot be instantiated but can contain abstract methods, and subclasses need to implement their abstract methods; Final is used to prohibit inheritance, rewriting, or multiple assignments, and is often used for constant declarations; inner classes are divided into member, local, static, and anonymous classes, each with scope and access restrictions, and are suitable for code encapsulation in different scenarios.

static

static keyword

static can modify member variables, member methods, code blocks, and nested classes. Members modified by static belong to the class itself and do not belong to a specific object.

static member variable

Static member variables are shared among all objects of the same class and are usually accessed using class names.

public class Person {
    private String name;
    private static int count;

    public Person(String name) {
        this.name = name;
        count++;
    }

    public static int getCount() {
        return count;
    }

    public static void main(String[] args) {
        new Person("Tom");
        new Person("Jerry");
        System.out.println(Person.getCount());
    }
}

The first time a class is actively used, the JVM completes the class loading, connection, and initialization. Explicit assignments of static fields and static code blocks are executed in the order written during class initialization.

static member method

Static methods can be called directly through the class name.

public class Person {
    public static void evolve() {
        System.out.println("人类的进化");
    }

    public static void main(String[] args) {
        Person.evolve();
    }
}

Static methods have no current objects, so they cannot use this or super, nor can they directly access instance members. When you need to access instance members, you must first obtain an object reference.

instance initialization block

A normal block of code written directly in a class without a method name is called an instance initialization block and is often called a construction code block. Each time an object is created, it is executed before the constructor body.

public class Person {
    {
        System.out.println("执行实例初始化块");
    }

    public Person() {
        System.out.println("执行无参构造器");
    }

    public Person(String name) {
        System.out.println("执行有参构造器:" + name);
    }
}

The instance initialization block is suitable for holding initialization code that multiple constructors need to execute. The compiler will merge it into each constructor and ensure that the parent class constructor is executed first before the initialization code for the current class instance is executed.

static initialization block

The static initialization block is decorated with static, is executed at class initialization, and is usually executed only once per class loader.

public class Person {
    static {
        System.out.println("执行静态初始化块");
    }
}

When creating subclass objects, the common initialization sequence is as follows:

  1. Parent static fields and static initialization blocks.

  2. Subclasses static fields and static initialization blocks.

  3. Parent class instance fields and instance initialization blocks.

  4. Parent class constructor.

  5. Subclass instance fields and instance initialization blocks.

  6. Subclass constructor.

Field initialization statements and initialization blocks in the same class are executed in the order in the source code.

Single-case design pattern

The singleton pattern is used to ensure that a class only provides one shared instance to the outside world and provides a unified access entry.

Hungry Han style

Hungry style creates objects during class initialization, which is simple and naturally thread safe during class initialization.

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

The key points are as follows:

  1. The constructor is privatized to prevent direct external creation of objects.

  2. Use static fields to save unique instances.

  3. Return the instance using a static method.

lazy man style

The simplest slacker writing can create multiple objects in a multithreaded environment, so it cannot be used directly in concurrency scenarios.

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Using synchronized can ensure correctness, but each call requires entering the synchronization method. Real projects can also use static inner classes or enumerations to implement singletons.

abstract (abstract)

abstract can modify classes and methods.

abstract class

Abstract classes cannot be directly instantiated and can contain fields, constructors, ordinary methods, and abstract methods. As long as there are abstract methods in a class, the class must be declared abstract; an abstract class can also contain no abstract methods.

abstract method

Abstract methods only have method declarations and no method bodies. Concrete subclasses must implement the abstract methods they inherit, otherwise the subclasses must also be declared abstract classes.

public abstract class TestAbstract {
    private String name;
    private int age;

    public TestAbstract() {
    }

    public TestAbstract(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public abstract void method();
}
public class TestSub extends TestAbstract {
    @Override
    public void method() {
        System.out.println("实现抽象方法");
    }
}

Abstract classes can define public processes and declare as abstract methods steps that must be decided by subclasses.

public abstract class Shape {
    public abstract double area();

    public static double areaSum(Shape[] shapes) {
        double sum = 0;
        for (Shape shape : shapes) {
            sum += shape.area();
        }
        return sum;
    }
}

final keyword

final can modify classes, methods, and variables.

final class

Classes modified by final cannot be inherited.

public final class Utility {
}

final method

Methods modified by final cannot be overridden by subclasses.

final variable

Variables modified by final can only be assigned once.

final int age = 18;

If final modifies a reference variable, it cannot be redirected to another object, but it may still modify mutable properties within the original object.

final StringBuilder builder = new StringBuilder("Java");
builder.append(" SE");
// builder = new StringBuilder(); // 编译错误

An instance final field that is not assigned at the declaration is called a blank final field and must be assigned in the instance initialization block or in each constructor.

public class Person {
    private final int age;

    public Person() {
        age = 0;
    }

    public Person(int age) {
        this.age = age;
    }
}

Constants are usually decorated with public static final, and names are all capitalized and underlined.

public class Person {
    public static final String BIRTH_PLACE = "中国";
}

inner class

A class defined within another class is called an inner class or nested class. It is often used to encapsulate auxiliary logic that only serves external classes.

member internal class

Member inner classes are external class objects and can directly access instance members of external classes.

public class TestOuter {
    private String outerName;

    class TestInner {
        public void test() {
            outerName = "test";
        }
    }
}

When creating a member inner class object outside of an outer class, you need to first create the outer class object.

TestOuter outer = new TestOuter();
TestOuter.TestInner inner = outer.new TestInner();

local interior class

Classes defined in methods or other local scopes are called local inner classes and can only be used in that scope.

public void method() {
    class TestInner {
        public void test() {
            System.out.println("局部内部类");
        }
    }

    new TestInner().test();
}

The local variable accessed by the local inner class must be final or in fact final.

statically nested classes

Nested classes decorated by static do not rely on external class objects and can only directly access static members of the external class.

public class TestOuter {
    private static String outerName;

    static class TestInner {
        public void test() {
            outerName = "test";
        }
    }
}

External class instances are not required when creating objects.

TestOuter.TestInner inner = new TestOuter.TestInner();

anonymous inner classes

Anonymous inner classes can be used when the implementation of an interface or parent class is used only once.

Person person = new Person() {
    @Override
    public void eat() {
        System.out.println("执行 eat 方法");
    }
};
person.eat();

An anonymous inner class does not have an explicit class name, but the compiler still generates the corresponding class. When you need to create the same implementation repeatedly, you should define named classes to avoid duplicate code.

Event Monitoring Example

public class Cal {
    private final JButton button1 = new JButton("1");
    private final JButton button2 = new JButton("2");
    private final JButton buttonAdd = new JButton("+");

    public Cal() {
        buttonAdd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                // 实现相加功能
            }
        });

        button1.addActionListener(new NumberAction());
        button2.addActionListener(new NumberAction());
    }

    class NumberAction implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            // 把按钮文字显示到显示区域
        }
    }
}

If you enjoyed this, leave a comment~

... Page views
© 2026 跨越星轨的客 @Hoshiumi
Powered by theme astro-koharu · Inspired by Shoka