static
静态变量(类变量)
- 所有类的实例共享同一静态变量,存储在方法区,节省内存。
- 可通过 类名.变量名 直接访问,无需创建对象。
静态方法
- 属于类本身,通过 类名.方法名() 调用,无需实例化对象。
- 不能访问非静态成员(无 this 指针),常用于工具函数
静态代码块
- 在类加载时执行一次,用于初始化静态资源。
静态内部类
- 与外部类实例无关,可直接访问外部类的静态成员。
继承:
空参是虚拟机自动给的
在Java中,super 关键字主要用于继承关系中,允许子类访问父类的成员(方法、变量和构造方法)。以下是 super 关键字的核心用途及注意事项:
1. 调用父类构造方法
语法:super(参数列表);
规则:
必须在子类构造方法的第一行使用。
若父类没有无参构造方法,子类构造方法必须显式调用父类的有参构造方法。
若父类有无参构造方法,子类构造方法可省略 super()(编译器自动添加)。
示例:
java
复制
class Parent {
Parent(int x) {
System.out.println("Parent构造方法: " + x);
}
}
class Child extends Parent {
Child() {
super(10); // 显式调用父类有参构造方法
System.out.println("Child构造方法");
}
}
2. 调用父类被覆盖的方法
语法:super.方法名(参数列表);
用途:当子类重写父类方法后,仍可通过 super 调用父类原始方法。
示例:
java
复制
class Parent {
void print() {
System.out.println("Parent的print方法");
}
}
class Child extends Parent {
@Override
void print() {
super.print(); // 调用父类的print方法
System.out.println("Child的print方法");
}
}
3. 访问父类的成员变量
语法:super.变量名
用途:当子类与父类有同名变量时,super 可明确访问父类变量(避免歧义)。
示例:
java
复制
class Parent {
int x = 10;
}
class Child extends Parent {
int x = 20;
void show() {
System.out.println(super.x); // 输出父类的x(10)
System.out.println(this.x); // 输出子类的x(20)
}
}
注意事项
静态上下文中不可用:super 指向父类实例,不能在 static 方法中使用。
访问权限限制:父类成员需为 protected 或 public,否则子类无法通过 super 访问。
多层继承限制:super 仅能访问直接父类,不能跨级访问“祖父类”。
示例总结
java
复制
class Parent {
int x;
Parent(int x) { this.x = x; }
void display() { System.out.println("Parent的x: " + x); }
}
class Child extends Parent {
int x;
Child(int x) {
super(x); // 调用父类构造方法
this.x = x * 2; // 子类x为父类x的2倍
}
@Override
void display() {
super.display(); // 调用父类方法
System.out.println("Child的x: " + x);
System.out.println("通过super访问父类x: " + super.x);
}
}
public class Test {
public static void main(String[] args) {
Child child = new Child(5);
child.display();
}
}
输出:
复制
Parent的x: 5
Child的x: 10
通过super访问父类x: 5
通过合理使用 super,可以清晰管理继承关系中的构造方法调用、方法重写和变量访问,确保代码逻辑的准确性和可维护性。
方法的重写:
在 Java 中,方法重写(Override) 是面向对象编程中多态性的核心体现,它允许子类重新定义父类的方法,实现 运行时多态。以下是方法重写的规则、本质及其底层实现机制:
一、方法重写的规则
方法签名一致
方法名、参数列表(类型、顺序、数量)必须与父类方法完全一致。
返回类型可以是父类方法返回类型的子类(协变返回类型,Java 5+ 支持)。
访问权限不能更严格
子类方法的访问修饰符必须 ≥ 父类方法(例如父类方法是 protected,子类可以是 protected 或 public)。
异常范围不能扩大
子类方法抛出的受检异常(checked exception)必须 ≤ 父类方法声明的异常范围(可抛出更具体或更少的异常)。
非静态方法才能重写
static、private、final 方法不能被重写(@Override 注解会报错)。
二、方法重写的本质
方法重写的本质是 动态绑定(Dynamic Binding),即程序在 运行时 根据对象的实际类型决定调用哪个方法,而非编译时的引用类型。这是实现多态的核心机制。
底层实现机制
虚方法表(Virtual Method Table, vtable)
JVM 为每个类维护一个 虚方法表,存储该类所有可被重写的方法入口地址。
子类的虚方法表中:
未被重写的方法:直接指向父类方法入口。
被重写的方法:指向子类自己的方法入口。
方法调用指令 invokevirtual
当通过对象引用调用方法时(如 obj.method()),JVM 使用 invokevirtual 指令。
动态分派流程:
根据对象的实际类型(而非引用类型)找到对应的虚方法表。
从虚方法表中查找方法对应的入口地址。
执行具体的方法实现。
三、示例代码与内存分析
java
复制
class Animal {
public void speak() {
System.out.println("Animal speaks");
}
}
class Dog extends Animal {
@Override
public void speak() {
System