Java 构造函数与修饰符详解:初始化对象与控制权限


在 Java 中,构造函数和修饰符是面向对象编程中两个重要的概念。构造函数用于初始化对象的状态,而修饰符用于控制类、方法和变量的访问权限。以下是对这两个概念的详细解析。

构造函数

什么是构造函数?

构造函数是用于创建和初始化对象的特殊方法。它在对象实例化时自动调用,主要任务是为对象的实例变量赋初值。

构造函数的特点

  • 名称必须与类名相同
  • 没有返回类型,即使是 void 也不能声明。
  • 可以重载,即一个类可以有多个构造函数,只要参数列表不同。

默认构造函数

如果类中没有定义任何构造函数,Java 会提供一个默认的无参构造函数。

public class Example {
    // 默认构造函数,由 Java 自动提供
    public Example() {
    }
}

有参构造函数

用于在创建对象时传递参数,以便初始化实例变量。

public class Person {
    private String name;
    private int age;

    // 有参构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

构造函数重载

同一个类中可以有多个构造函数,只要它们的参数列表不同。

public class Rectangle {
    private double length;
    private double width;

    // 无参构造函数
    public Rectangle() {
        this.length = 1.0;
        this.width = 1.0;
    }

    // 有参构造函数
    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }
}

调用构造函数

public class Main {
    public static void main(String[] args) {
        // 调用无参构造函数
        Rectangle rect1 = new Rectangle();

        // 调用有参构造函数
        Rectangle rect2 = new Rectangle(2.0, 3.0);

        // 调用 Person 类的有参构造函数
        Person person = new Person("Alice", 30);
    }
}

this() 和 super() 调用

  • this():调用当前类的其他构造函数。
  • super():调用父类的构造函数。
public class Box {
    private double width, height, depth;

    // 三参数构造函数
    public Box(double width, double height, double depth) {
        this.width = width;
        this.height = height;
        this.depth = depth;
    }

    // 无参构造函数,调用三参数构造函数
    public Box() {
        this(1.0, 1.0, 1.0);
    }
}

public class ColoredBox extends Box {
    private String color;

    // 调用父类的三参数构造函数
    public ColoredBox(double width, double height, double depth, String color) {
        super(width, height, depth);
        this.color = color;
    }
}

修饰符

修饰符用于控制类、方法和变量的访问权限及其行为。Java 提供了多种修饰符,主要分为访问修饰符和非访问修饰符。

访问修饰符

1. public

  • :任何类都能访问。
  • 成员:可以被任何其他类访问。
public class Example {
    public int value;

    public void display() {
        System.out.println("Value: " + value);
    }
}

2. protected

  • :不能用于顶层类。
  • 成员:同一包中的类和任何子类(即使不在同一包中)都能访问。
public class Example {
    protected int value;

    protected void display() {
        System.out.println("Value: " + value);
    }
}

3. 无修饰符(默认)

  • :只能被同一包中的类访问。
  • 成员:只能被同一包中的类访问。
class Example {
    int value;

    void display() {
        System.out.println("Value: " + value);
    }
}

4. private

  • :不能用于顶层类。
  • 成员:只能被同一类中的其他成员访问。
public class Example {
    private int value;

    private void display() {
        System.out.println("Value: " + value);
    }
}

非访问修饰符

1. static

  • 变量:属于类而不是实例,所有实例共享同一个变量。
  • 方法:属于类,可以不创建实例直接调用。
public class Example {
    public static int count;

    public static void displayCount() {
        System.out.println("Count: " + count);
    }
}

2. final

  • :不能被继承。
  • 方法:不能被子类重写。
  • 变量:值不能被修改。
public final class Example {
    public final int VALUE = 10;

    public final void display() {
        System.out.println("Value: " + VALUE);
    }
}

3. abstract

  • :不能被实例化,必须被子类继承。
  • 方法:没有实现,必须在子类中实现。
public abstract class Example {
    public abstract void display();
}

public class ConcreteExample extends Example {
    @Override
    public void display() {
        System.out.println("Concrete implementation");
    }
}

4. synchronized

  • 方法:确保线程安全,同一时间只能有一个线程访问。
public class Example {
    public synchronized void display() {
        System.out.println("Thread-safe method");
    }
}

5. volatile

  • 变量:提示 JVM 变量可能会被其他线程修改,不会从缓存中读取,而是从主存中读取。
public class Example {
    private volatile boolean flag;

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public boolean getFlag() {
        return flag;
    }
}

6. transient

  • 变量:在序列化过程中不会被包含。
public class Example implements Serializable {
    private transient int value;
}

总结

通过合理使用构造函数和修饰符,可以有效地初始化对象、控制类和成员的访问权限以及行为。构造函数用于初始化对象的状态,而修饰符则提供了强大的访问控制和行为控制能力,是编写高质量 Java 代码的基础。


原文链接:codingdict.net