Java修饰符

像其他语言一样,Java可以使用修饰符。在 Java 里,修饰符用于定义方法或者变量特性与访问权限

主要有两类修饰符:

  • 访问控制修饰符 :

    名称 含义
    default 也称为包访问权限。如果一个类、方法或属性没有使用任何访问修饰符,那么它只能被同一个包内的其他类访问。
    public 具有公共访问权限,被 public 修饰的类、方法或属性可以被任何包中的任何类访问
    protected 具有受保护的访问权限。被 protected 修饰的成员可以被同一个包内的其他类访问也可以被不同包中的子类访问
    private 具有私有访问权限,被 private 修饰的方法或属性只能在定义它们的类内部访问其他类无法直接访问

    开放程度:public(所有人) > protected(自家人) > default(在家(包)里的人) > private(自己)

  • 非访问控制修饰符 :

    名称 含义
    final 修饰类:表示该类不能被继承
    修饰方法:表示该方法不能被重写
    修饰变量:表示该变量一旦被赋值,就不能再被修改,成为常量
    abstract 修饰类:表示该类是抽象类,不能被实例化,主要用于作为其他类的基类。抽象类中可以包含抽象方法和非抽象方法。
    修饰方法:表示该方法是抽象方法,只有方法声明,没有方法体,需要在子类中实现。
    static 修饰变量:表示该变量是类变量,被所有类的实例共享,不需要创建对象就可以通过类名直接访问
    修饰方法:表示该方法是类方法,同样不需要创建对象就可以通过类名直接调用,并且在静态方法中不能直接访问非静态成员(能访问静态成员)。
    synchronized 用于修饰方法或代码块,保证在同一时刻只有一个线程可以访问该方法或代码块,主要用于解决多线程并发访问时的数据同步问题

访问控制修饰符

1. default(默认,不写修饰符时)

  • 含义:也称为包访问权限。如果一个类、方法或属性没有使用任何访问修饰符,那么它只能被同一个包内的其他类访问。

  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    // 定义在 com.example 包下
    package com.example;

    class DefaultAccessClass {
    void defaultMethod() {
    System.out.println("This is a default access method.");
    }
    }

在同一个包内的其他类可以调用 defaultMethod,但不同包的类无法调用。

2. public

  • 含义:具有公共访问权限,被 public 修饰的类、方法或属性可以被任何包中的任何类访问

  • 示例

    1
    2
    3
    4
    5
    6
    7
    package com.example;

    public class PublicAccessClass {
    public void publicMethod() {
    System.out.println("This is a public access method.");
    }
    }

无论在哪个包中的类,都可以创建 PublicAccessClass 的对象并调用 publicMethod

3. protected

  • 含义:具有受保护的访问权限。被 protected 修饰的成员可以被同一个包内的其他类访问也可以被不同包中的子类访问

  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 父类,在 com.example 包下
    package com.example;

    public class ParentClass {
    protected void protectedMethod() {
    System.out.println("This is a protected method.");
    }
    }

    // 子类,在不同包下
    package another.example;
    import com.example.ParentClass;

    public class ChildClass extends ParentClass {
    public void callProtectedMethod() {
    protectedMethod(); // 可以调用父类的 protected 方法
    }
    }

4. private

  • 含义:具有私有访问权限,被 private 修饰的方法或属性只能在定义它们的类内部访问其他类无法直接访问

  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class PrivateAccessClass {
    private int privateField = 10;
    private void privateMethod() {
    System.out.println("This is a private method.");
    }

    public void accessPrivateMembers() {
    privateField = 20;
    privateMethod();
    }
    }

外部类不能直接访问 privateFieldprivateMethod

非访问控制修饰符

1. final

  • 含义:

    • 修饰类:表示该类不能被继承
    • 修饰方法:表示该方法不能被重写
    • 修饰变量:表示该变量一旦被赋值,就不能再被修改,成为常量
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // final 类不能被继承
    final class FinalClass {
    // final 方法不能被重写
    public final void finalMethod() {
    System.out.println("This is a final method.");
    }
    }

    class AnotherClass {
    // final 变量
    final int FINAL_VARIABLE = 10;
    }

2. abstract

  • 含义:

    • 修饰类:表示该类是抽象类,不能被实例化,主要用于作为其他类的基类。抽象类中可以包含抽象方法和非抽象方法。
    • 修饰方法:表示该方法是抽象方法,只有方法声明,没有方法体,需要在子类中实现。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 抽象类
    abstract class AbstractClass {
    // 抽象方法
    public abstract void abstractMethod();
    // 非抽象方法
    public void normalMethod() {
    System.out.println("This is a normal method.");
    }
    }

    // 子类实现抽象方法
    class ConcreteClass extends AbstractClass {
    @Override
    public void abstractMethod() {
    System.out.println("Implementing the abstract method.");
    }
    }

3. static

  • 含义:

    • 修饰变量:表示该变量是类变量,被所有类的实例共享,不需要创建对象就可以通过类名直接访问
    • 修饰方法:表示该方法是类方法,同样不需要创建对象就可以通过类名直接调用,并且在静态方法中不能直接访问非静态成员(能访问静态成员)。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class StaticExample {
    // 静态变量
    static int staticVariable = 10;
    // 静态方法
    public static void staticMethod() {
    System.out.println("This is a static method.");
    }

    public static void main(String[] args) {
    // 直接通过类名访问静态变量和方法
    System.out.println(StaticExample.staticVariable);
    StaticExample.staticMethod();
    }
    }

4. synchronized

  • 含义:用于修饰方法或代码块,保证在同一时刻只有一个线程可以访问该方法或代码块,主要用于解决多线程并发访问时的数据同步问题
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SynchronizedExample {
private int count = 0;

// 同步方法
public synchronized void increment() {
count++;
}

public static void main(String[] args) {
SynchronizedExample example = new SynchronizedExample();
// 创建多个线程访问同步方法
// 这里省略具体多线程代码,实际使用中可通过 Thread 类或 ExecutorService 实现
}
}

protected 成员的访问方式

在 Java 中,protectedprivate 都是访问修饰符,用于控制类、方法和变量的访问权限,但它们的访问规则有所不同。下面分别介绍 protected 成员的访问方式以及它与 private 的区别。

protected 修饰的成员(类、方法、变量)具有一定的访问权限规则,其访问方式如下:

1. 同一类内部

在定义 protected 成员的类内部,可以直接访问该成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
class ProtectedExample {
protected int protectedVariable = 10;

protected void protectedMethod() {
System.out.println("This is a protected method.");
}

public void accessWithinClass() {
// 在类内部可以直接访问 protected 变量和方法
System.out.println(protectedVariable);
protectedMethod();
}
}

2. 同一包内的其他类

在同一个包中的其他类,可以访问该类的 protected 成员。

1
2
3
4
5
6
7
8
9
// 同一个包中的另一个类
class AnotherClassInSamePackage {
public void accessProtectedMembers() {
ProtectedExample example = new ProtectedExample();
// 在同一包内可以访问 protected 变量和方法
System.out.println(example.protectedVariable);
example.protectedMethod();
}
}

3. 不同包中的子类

在同包的子类中,可以通过子类对象访问从父类继承来的 protected 成员,也可以在子类内部直接访问父类的 protected 成员。

1
2
3
4
5
6
7
8
9
10
11
// 父类在包 com.example.parent 中
package com.example.parent;

public class ParentClass {
protected int protectedVariable = 20;

protected void protectedMethod() {
System.out.println("This is a protected method in ParentClass.");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 子类在包 com.example.child 中
package com.example.child;
import com.example.parent.ParentClass;

public class ChildClass extends ParentClass {
public void accessProtectedFromParent() {
// 在子类内部可以直接访问父类的 protected 成员
System.out.println(protectedVariable);
protectedMethod();
}

public static void main(String[] args) {
ChildClass child = new ChildClass();
child.accessProtectedFromParent();

// 不同包的子类对象也可以访问继承的 protected 成员
System.out.println(child.protectedVariable);
child.protectedMethod();
}
}

protectedprivate 的区别

1. 访问权限范围

  • protected:如上述所说,protected 成员可以被同一类内部、同一包内的其他类以及不同包中的子类访问。
  • privateprivate 成员只能在定义它的类内部被访问,其他任何类(包括子类,同一包中的其他类)都无法直接访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class PrivateExample {
private int privateVariable = 30;

private void privateMethod() {
System.out.println("This is a private method.");
}

public void accessPrivateWithinClass() {
// 在类内部可以直接访问 private 变量和方法
System.out.println(privateVariable);
privateMethod();
}
}

class TryToAccessPrivate {
public void test() {
PrivateExample example = new PrivateExample();
// 下面两行代码会编译错误,因为 private 成员不能在类外部访问
// System.out.println(example.privateVariable);
// example.privateMethod();
}
}

2. 对继承的影响

  • protectedprotected 成员可以被不同包的子类继承和访问,这使得子类能够扩展和使用父类的功能。
  • privateprivate 成员不能被子类继承和直接访问,子类无法直接使用父类的 private 成员,这保证了类的封装性和数据的安全性。

来源:

- 豆包
- 我自己