We know our weakness. Now what will we do?
We’ll get stronger! We’ll get up and fight! – Natsu Dragneel
from Fairy Tail
类(Class)
定义对象的蓝图,包括属性和方法。就像是一个自定义的数据类型,你仅仅进行定义,没有创建实际的变量。
一个典型类如下:
类的组成
1. 成员变量
定义:用于存储对象状态的数据。它声明在类中、方法体之外,每个对象都会拥有自己的一份副本。
定义方法:[ ]中的内容可以省略
1
| [访问修饰符] 数据类型 变量名 [= 初始值]
|
语法:[访问修饰符] 数据类型 变量名 [= 初始值];
- 访问修饰符: 如
public
, private
, protected
, 默认 (package-private)
,控制成员变量的访问权限。
- 数据类型: 如
int
, float
, String
, boolean
, 以及自定义的类类型等。
- 变量名: 遵循 Java 变量命名规则。
- 初始值 (可选): 在声明时为变量赋初始值。如果没有显式赋值,则会使用默认值(例如,数值类型默认为 0,布尔类型默认为 false,引用类型默认为 null)
1 2 3 4 5 6 7
| public class Car { public String color; private int speed; protected String model; boolean isRunning = false; }
|
2. 构造方法
定义:特殊的方法,用于创建对象并初始化对象的成员变量。也就是在创建对象的时候自动调用的函数。
定义方法:
构造方法的名字需于类名完全相同。
特点:
- 没有返回值
- 每个类至少有一个构造方法(多个构造方法涉及方法的重载)
- 若没有显示指定构造方法,编译器会自动生成一个无参默认构造方法
- 构造方法的访问修饰符决定了哪些类可以创建该类的实例。
访问修饰符 |
构造方法访问级别 |
public |
任何类都可以创建该类的实例 |
protected |
同一个包中的类和子类可以创建该类的实例 |
private |
只能在该类内部创建该类的实例 |
默认 |
只有同一个包中的类可以创建该类的实例 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Car { public String color; private int speed;
public Car() { this.color = "white"; this.speed = 0; }
public Car(String color, int speed) { this.color = color; this.speed = speed; } }
|
3. 成员方法
定义:定义对象的行为,可以执行特定的操作
定义方法:
1 2 3 4
| [访问修饰符] [static] [返回类型] 方法名(参数列表) [throws 异常列表] { }
|
static
(可选): 表示静态方法,属于类本身,而不是类的实例。通过static声明的方法,无需创建对象实例就可以直接使用,反之,未用static声明的方法。只能由创建后的实例调用。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Car { public String color; private int speed;
public void accelerate(int increment) { this.speed += increment; }
public int getSpeed() { return this.speed; } }
|
4. 静态成员
定义:使用 static
关键字修饰的成员变量和方法。它们属于类本身,而不是类的实例。
- 特点:
- 可以通过类名直接访问,无需创建对象。
- 所有该类的实例共享同一个静态成员的副本。
- 静态方法不能直接访问非静态成员(实例变量和方法),因为静态方法不属于任何特定的对象。
1 2 3 4 5 6 7 8 9 10 11
| public class Car { public static int carCount = 0;
public Car() { carCount++; } public static int getCarCount() { return carCount; } }
|
5. 内部类
定义:在类内部定义的类。
分类:
- 成员内部类: 与类的成员变量类似,在类中直接定义。
- 静态内部类: 使用
static
关键字修饰的内部类。
- 局部内部类: 在方法或代码块中定义的类。
- 匿名内部类: 在创建对象时定义的没有名字的类。
特点:
- 内部类可以访问外部类的所有成员,包括私有成员。
- 声明内部类的外部类也可以访问内部类的的所有成员,包括私有成员。
1 2 3 4 5 6 7 8 9
| public class HelloWorld { private class Car{ private static String car = "This is a car"; } public static void main(String[] args) { System.out.println("Hello World"); System.out.println(Car.car); } }
|
运行结果为:

以上就是一个完整的Java类通常包含的要素。
对象(Object)
对象的是类的实例,是创建的实际变量,分配实际内存空间后的实例,具有状态和行为。
典型创建实例如下:
若自定义了构造方法,则可以在括号中传入对应参数,应用于实例的初始化。
假设我们自定义一个类如下:
1 2 3 4 5 6 7 8 9 10 11 12
| class Car { public String color; public static int myCarCount = 0; public Car(String color){ this.color = color; myCarCount++; } public void changeColor(String color){ this.color = color; } }
|
在类中,我们可以通过this关键字来表示创建后的实例,每个实例中的this都互不影响,只表示自己实例中的值。但是对于类中的静态变量(static修饰)来说,并不能通过this来访问,静态变量不属于任何实例,所有该类的实例共享一个静态变量。
实例化对象:
1
| Car myCar = new Car("Blue");
|
访问对象中的变量:
1 2
| myCar.color System.out.println("my car's color is " + myCar.color);
|
访问对象中的方法:
1
| myCar.changeColor("green");
|
访问类中的静态变量和方法:
1 2
| Car.myCarCount; System.out.println("I have " + Car.myCarCount + " cars");
|
给出如下程序:
1 2 3 4 5 6 7 8 9
| public class HelloWorld { public static void main(String[] args) { Car myCar = new Car("Blue"); System.out.println("my car's color is " + myCar.color); myCar.changeColor("green"); System.out.println("my car's color is " + myCar.color); System.out.println("I have " + Car.myCarCount + " cars"); } }
|
运行结果如下:

静态代码块与非静态代码块(构造块)
静态代码块
静态代码块属于类,而不是实例,会在类加载时自动执行一次,用于初始化静态变量或做类级别的准备工作。
1 2 3 4 5
| class Parent { static { System.out.println("父类静态代码块"); } }
|
非静态代码块/构造块
非静态代码块属于实例,每次创建实例对象时都会执行。用于初始化实例变量。或执行一些实例级别的准备逻辑。
- 编译器会将非静态代码块的内容自动插入到构造方法的前面。
1 2 3 4 5
| class Parent { { System.out.println("父类构造块"); } }
|
当有如下的子类与父类时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Parent { static { System.out.println("① 父类静态代码块"); }
{ System.out.println("③ 父类构造块"); }
public Parent() { System.out.println("④ 父类构造方法"); } }
class Child extends Parent { static { System.out.println("② 子类静态代码块"); }
{ System.out.println("⑤ 子类构造块"); }
public Child() { System.out.println("⑥ 子类构造方法"); } }
public class Main { public static void main(String[] args) { new Child(); } }
|
运行顺序如下:
1 2 3 4 5 6
| ① 父类静态代码块 ② 子类静态代码块 ③ 父类构造块 ④ 父类构造方法 ⑤ 子类构造块 ⑥ 子类构造方法
|