Java 每日一刊(第13期):this super static
“优秀的代码不仅仅是给机器看的,更是给人看的。”
前言
这里是分享 Java 相关内容的专刊,每日一更。
本期将为大家带来以下内容:
- this 关键字
- super 关键字
- static 关键字
this
关键字
this
关键字是 Java 中最常见的关键字之一,它用于表示“当前对象”的引用。它通常用于区分实例变量和方法参数,以及在对象的方法内部引用自身。在对象的内部方法中,this
可以用来调用成员变量、方法和构造方法。
访问当前对象的成员变量
当方法的参数名称与当前类的成员变量名称相同时,this
可以用来区分它们。下面是一个经典的例子:
public class Person {
private String name;
public Person(String name) {
this.name = name; // 使用 this 关键字区分成员变量和参数
}
public void display() {
System.out.println("Name: " + this.name); // this 引用当前对象的 name 变量
}
}
在上面的代码中,this.name
表示当前对象的 name
成员变量,而 name
表示方法参数。通过 this
关键字,我们可以清楚地表明要访问的是当前对象的成员变量。
调用当前类的构造方法
this()
还可以在构造方法中调用类的其他构造方法,避免重复代码。这种用法也称为 构造器链。在一个类中可以通过 this()
互相调用多个构造器:
public class Person {
private String name;
private int age;
public Person(String name) {
this(name, 0); // 调用另一个构造方法
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void display() {
System.out.println("Name: " + name + ", Age: " + age);
}
}
在这个例子中,this(name, 0)
调用了带两个参数的构造方法,这不仅减少了重复代码,还增强了代码的可维护性。
返回当前对象
this
关键字还可以用来返回当前对象,这在需要链式调用时非常有用。例如,很多流式 API(如 StringBuilder
或 Stream
)使用这种模式:
public class Person {
private String name;
public Person setName(String name) {
this.name = name;
return this; // 返回当前对象,支持链式调用
}
public void display() {
System.out.println("Name: " + name);
}
public static void main(String[] args) {
new Person().setName("John").display(); // 链式调用
}
}
通过 this
返回当前对象,可以使方法链式调用,代码更加简洁、优雅。
super
关键字
super
关键字用于引用父类中的成员变量、方法以及构造方法。在子类和父类有继承关系时,super
可以帮助子类访问父类中的实现。它主要用于以下三种场景:
调用父类的构造方法
当子类继承父类时,如果父类有参数化的构造方法,子类通常需要通过 super()
来显式调用父类的构造方法。调用父类构造方法必须是子类构造方法的 第一行,否则编译器会报错。
public class Person {
protected String name;
public Person(String name) {
this.name = name;
}
}
public class Student extends Person {
private int grade;
public Student(String name, int grade) {
super(name); // 显式调用父类的构造方法
this.grade = grade;
}
public void display() {
System.out.println("Name: " + name + ", Grade: " + grade);
}
}
在这个例子中,Student
类通过 super(name)
调用了父类 Person
的构造方法,确保在子类中初始化父类的成员变量。
访问父类的成员变量
当子类中的成员变量与父类中的成员变量同名时,可以使用 super
来明确访问父类的成员变量:
public class Person {
protected String name = "Parent";
}
public class Student extends Person {
protected String name = "Child";
public void printName() {
System.out.println(super.name); // 访问父类的 name
System.out.println(this.name); // 访问子类的 name
}
}
输出结果为:
Parent
Child
在这个例子中,通过 super.name
明确地访问了父类中的 name
成员变量。
调用父类的方法
如果子类重写了父类的方法,而你在子类中仍然想调用父类的方法,可以通过 super
关键字实现:
public class Person {
public void display() {
System.out.println("Person display");
}
}
public class Student extends Person {
@Override
public void display() {
super.display(); // 调用父类的 display() 方法
System.out.println("Student display");
}
}
输出结果为:
Person display
Student display
通过 super.display()
,我们可以在子类中调用父类的 display
方法,保留父类方法的行为,同时扩展子类的功能。
static
关键字
static
关键字用于修饰类的静态成员(变量或方法),这些成员属于类本身,而不是类的实例。它主要用于实现共享数据或工具类的通用方法。
静态变量
静态变量(也称为类变量)是类的所有实例共享的变量。无论创建了多少个对象,静态变量只有一份内存空间,所有实例都可以访问和修改它:
public class Counter {
public static int count = 0; // 静态变量
public Counter() {
count++; // 每创建一个实例,count 增加 1
}
public static void displayCount() {
System.out.println("Count: " + count); // 静态方法可以访问静态变量
}
}
public class Main {
public static void main(String[] args) {
new Counter();
new Counter();
Counter.displayCount(); // 输出 2
}
}
静态变量 count
是类的所有实例共享的,当创建了多个对象时,它们会共同维护同一个 count
变量。
静态方法
静态方法可以直接通过类名调用,而不需要实例化对象。静态方法通常用于实现不依赖实例的工具类方法或逻辑:
public class MathUtil {
public static int add(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
int result = MathUtil.add(5, 10); // 通过类名直接调用静态方法
System.out.println(result); // 输出 15
}
}
静态方法只能访问静态变量或其他静态方法,不能直接访问非静态的成员变量或方法,因为它们不依赖于具体的实例。
静态代码块
静态代码块在类加载时执行一次,通常用于初始化类的静态成员或执行一些只需进行一次的操作:
public class Example {
static {
System.out.println("Static block executed");
}
public static void main(String[] args) {
Example ex = new Example(); // 静态代码块在类加载时执行
}
}
在上面的代码中,无论创建多少个 Example
对象,静态代码块只会在类加载时执行一次。
本期小知识
在 Java 构造方法中,this()
和 super()
是互斥的,不能在同一个构造方法中同时使用。它们都必须出现在构造方法的第一行,this()
用于调用当前类的其他构造方法,而 super()
用于调用父类的构造方法。