Java 中类的组成成分有哪些?

奋斗的软件工程师 / 2024-03-04 / 原文

Java 中类的组成成分有哪些?

在 Java 中,类是构成程序的基本单元。类由以下几个部分组成:

类名:用于标识类的名称。

修饰符:用于控制类的访问权限。

成员变量:用于存储类的数据。

成员方法:用于定义类的行为。

构造方法(构造器):用于创建类的实例。

内部类:【成员、静态、局部、匿名】可以将一个类的定义放在另外一个类的定义内部。

代码块:【静态、局部、构造、同步】用于在类中定义一段代码,该代码块可以被多个成员方法访问。

1. 类名

类名是类的标识符,必须遵循以下规则:

  • 必须以字母、下划线或美元符号开头。

  • 只能包含字母、数字、下划线和美元符号。

  • 不能使用 Java 关键字。

2. 修饰符

修饰符用于控制类的访问权限。Java 中的修饰符包括:

  • public:公共的,可以在任何地方访问。

  • protected:受保护的,只能在类本身及其子类中访问。

  • package-private:缺省,只有在同一个包中的类才能访问。

  • private:私有的,只能在类内部访问。

3. 成员变量

成员变量用于存储类的数据。成员变量可以是任何 Java 数据类型,包括基本数据类型和引用数据类型。

4. 成员方法

成员方法用于定义类的行为。成员方法可以是任何 Java 数据类型,包括基本数据类型和引用数据类型。

5. 构造方法

构造方法用于创建类的实例。构造方法的名称必须与类名相同,并且不能指定返回值类型。

6.内部类

可以将一个类的定义放在另外一个类的定义内部,可以提高代码的 结构性 和 可维护性。

成员内部类

成员内部类是最常见的内部类,它和外部类的成员变量一样,定义在类的内部,可以声明访问修饰符。

特点:

  • 可以访问外部类的所有成员(包括私有成员和静态成员)。
  • 不可以定义静态成员和方法,因为内部类是外部类的一个成员,只有当外部类初始化时,内部类才能初始化,静态变量属于类级别,在类加载的时候就初始化,所以两者本身在语法上就有矛盾。
  • 但可以定义常量。
public class OuterClass {

    private int num = 10;

    public class InnerClass {

        public void printNum() {
            System.out.println(num); // 可以访问外部类的私有成员
        }
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.printNum();
    }
}

静态内部类

静态内部类与成员内部类类似,但它属于外部类的静态成员,与外部类的实例无关。

特点:

  • 可以访问外部类的静态成员,但不能访问外部类的非静态成员(包括私有成员)。

  • 可以定义静态成员和方法。

public class OuterClass {

    private static int num = 10;

    public static class InnerClass {

        public static void printNum() {
            System.out.println(num); // 可以访问外部类的静态成员
        }
    }

    public static void main(String[] args) {
        OuterClass.InnerClass.printNum(); // 不需要创建外部类的实例
    }
}

局部内部类-鸡肋,食之无味···

局部内部类定义在方法或代码块中,只能在该方法或代码块内访问。
特点:

  • 可以访问该方法或代码块中的所有变量,包括局部变量。

  • 只能在定义它的方法或代码块内使用。

public class OuterClass {

    public void printNum() {
        int num = 10;

        class InnerClass {

            public void print() {
                System.out.println(num); // 可以访问局部变量
            }
        }

        InnerClass innerClass = new InnerClass();
        innerClass.print();
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.printNum();
    }
}

匿名内部类-重点

匿名内部类是局部内部类的简写形式,没有类名,直接使用 new 操作符创建。

特点:

  • 可以访问该方法或代码块中的所有变量,包括局部变量。

  • 只需创建一次,不能使用类名引用。

public class App {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.eat();// 猫吃鱼~~~

        new Animal() {
            public void eat() {
                System.out.println("猫吃鱼~~~");
            }

        }.eat();
    }
}

abstract class Animal {
    public abstract void eat();

}

class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼~~~");
    }
}

7.代码块

静态代码块

定义: 使用 static {} 包裹起来的代码片段。

特点:

  • 仅执行一次,在类加载时执行,且优先于构造代码块执行。
  • 属于类,与对象无关,所有该类的对象共享该代码块中的内容。
  • 常用于初始化静态成员变量、注册驱动程序等。
public class StaticCodeBlock {

    static {
        System.out.println("静态代码块");
    }

    public StaticCodeBlock() {
        System.out.println("构造代码块");
    }

    public static void main(String[] args) {
        new StaticCodeBlock();
        new StaticCodeBlock();

    }
}

静态代码块
构造代码块
构造代码块

构造代码块

定义: 直接在类中定义且没有加 static 关键字的代码块。

特点:

  • 在创建对象时被调用,每次创建对象都会被调用,且优先于类构造函数执行。
  • 属于对象,与类无关,每个对象都有自己的代码块副本。
  • 常用于初始化成员变量、执行一些初始化操作等。
public class ConstructorCodeBlock {

    private int num;

    {
        num = 10;
        System.out.println("构造代码块");
    }

    public ConstructorCodeBlock() {
        System.out.println("构造函数");
    }

    public static void main(String[] args) {
        new ConstructorCodeBlock();
        new ConstructorCodeBlock();
    }
}
构造代码块
构造函数
构造代码块
构造函数

普通代码块

定义: 在方法或语句中出现的 {} 就称为普通代码块。

特点:

  • 作用域仅限于该 {} 内,离开 {} 后其内部的变量空间会被回收。
  • 常用于控制流程、局部变量声明等。
public class NormalCodeBlock {

    public static void main(String[] args) {
        int num = 1;
        {
            int a = 2;
            System.out.println("普通代码块:" + num + ", " + a);
        }
        // System.out.println(a); // 编译错误,a 无法访问
    }
}
普通代码块:1, 2

同步代码块

定义: 使用 synchronized 关键字包裹起来的代码块。

特点:

  • 同步代码块中的代码只能由一个线程执行,其它线程试图进入该代码块时会阻塞,直到该线程执行完毕。
  • 常用于解决多线程并发访问问题,保证数据的完整性和一致性。
```public class SynchronizedCodeBlock {

    private int num = 0;

    public void increase() {
        synchronized (this) {
            num++;
        }
    }

    public static void main(String[] args) {
        SynchronizedCodeBlock scb = new SynchronizedCodeBlock();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    scb.increase();
                }
            }).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(scb.num); // 10000
    }
}
10000