Java 中类的组成成分有哪些?
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