# Java 中的访问修饰符

> 原文： [https://javabeginnerstutorial.com/core-java-tutorial/access-modifier-in-java/](https://javabeginnerstutorial.com/core-java-tutorial/access-modifier-in-java/)

Java 中的访问修饰符可帮助您设置所需的类，变量和方法的访问级别。

有三个访问修饰符。 不包括默认访问修饰符。 默认值为访问控制，当未指定任何访问修饰符时将设置访问控制。

## 访问控制

*   `public`
*   `private`
*   `protected`
*   默认

访问修饰符（*某些或全部*）可以应用于*类，变量，方法*。

## 类的访问修饰符

Java 中的类只能使用`public`和默认访问修饰符。

### `public`

设置为`public`时，java 世界中所有可用的类都可以访问给定的类。

### 默认

当设置为默认值时，给定的类将可供同一包中定义的类访问。

## Java 类的访问修饰符表

| **可见性** | **公开访问修饰符** | **默认访问修饰符** |
| --- | --- | --- |
| **位于同一包中** | Yes | Yes |
| **来自同一个包** | Yes | NO |

## 实例和静态变量的访问修饰符

变量适用于所有下面提到的修饰符。

*   `public`
*   `private`
*   `protected`
*   默认

> 在检查在该类内部定义的变量的可见性之前，应检查该类的可见性。
> 
> 如果该类是可见的，则在该类内部定义的变量将是可见的。
> 
> 如果看不到类，则即使将其设置为`public`，也将无法访问任何变量。

### 默认

如果将变量设置为默认值，则同一包中定义的类将可以访问该变量。 在同一包中的类中定义的任何方法都可以访问变量或**继承**或**直接访问**。

### `public`

如果将变量设置为公开变量，则可以从 Java 世界中可用的任何类中进行访问。 任何类中的任何方法都可以访问给定变量或**继承**或**直接访问**。

### `protected`

如果将变量在类内设置为**受保护的**，则只能通过**继承**从相同或不同包中定义的子类中对其进行访问。

> 保护和默认之间的唯一区别是受保护的访问修饰符遵守**类-子类关系**，而默认则不。

### `private`

只能从定义变量的类内部访问定义的变量`private`。 此类变量不能从已定义的类外部访问，甚至不能在其子类中访问。

## Java 变量的访问修饰符表

| **可见性** | **公共访问修饰符** | **私有访问修饰符** | **受保护的访问修饰符** | **默认访问修饰符** |
| --- | --- | --- | --- | --- |
| **在同一个类中** | Yes | Yes | Yes | Yes |
| **来自同一包装中的任何类** | Yes | No | Yes | Yes |
| **来自同一包中的任何子类** | Yes | No | Yes | Yes |
| **来自不同包的任何子类** | Yes | No | Yes（**仅通过继承**） | No |
| **来自不同包装中的任何非子类** | Yes | No | No | No |

## 方法的访问修饰符

方法适用于以下所有修饰符。

### 默认

当“方法”设置为默认值时，同一包中定义的类将可以访问该方法。 在同一包中定义的任何类中的任何方法都可以访问给定的方法或**继承**或**直接访问**。

### `public`

将方法设置为`public`时，可以从 Java 世界中可用的任何类中访问它。 任何类中的任何方法都可以访问或**继承**或**直接访问**的给定方法，具体取决于类级别的访问。

`protected`

如果将方法设置为在类内部进行保护，则可以从在相同或不同包中定义的子类访问该方法。

> 受保护的访问权限和默认访问权限之间的唯一区别是受保护的访问修饰符遵守**的类-子类关系**，而默认的则不这样做。

`private`

只能从定义其的类内部访问定义为私有的方法。 此类方法无法从已定义的类外部访问，甚至不能从其子类访问。

## Java 方法的访问修饰符表

| **可见性** | **公共访问修饰符** | **私有访问修饰符** | **受保护访问修饰符** | **默认访问修饰符** |
| --- | --- | --- | --- | --- |
| **相同类中** | Yes | Yes | Yes | Yes |
| **来自同一包中的任何类** | Yes | No | Yes | Yes |
| **来自同一包中的任何子类** | Yes | No | Yes | Yes |
| **来自不同包的任何子类** | Yes | No | Yes（**仅通过继承**） | No |
| **来自不同包装中的任何非子类** | Yes | No | No | No |

## 局部变量的访问修饰符

*无法将*访问修饰符应用于局部变量。 只能将`final`应用于局部变量，该局部变量是[非访问修饰符](https://javabeginnerstutorial.com/core-java-tutorial/non-access-modifiers-in-java/ "Non Access Modifiers in Java")。

## 继承或直接访问之间的区别

下面说明了继承和直接访问之间的区别。

超类

```java
package com.jbt;

public class FirstClass {
    public int i;
    protected int j;
    private int k;
    int l;
} 
```

同一包中的子类

```java
package com.jbt;

class SecondClass extends FirstClass {

    void method() {
        System.out.println(i);
        System.out.println(j); // Respect the parent child relationship irrespective of package
        System.out.println(k); // Compilation Error
        System.out.println(l); // Accessible as it is in same package

        FirstClass cls = new FirstClass();
        System.out.println(cls.i);
        System.out.println(cls.j);
        System.out.println(cls.l);
        // Private variable will not be accessible here also.
        System.out.println(cls.k); // Compilation error
    }
} 
```

不同包中的子类

```java
package com.jbt.newpackage;

import com.jbt.FirstClass;

class SecondClass extends FirstClass {

    void method() {
        // Access through inheritance
        System.out.println(i);
        System.out.println(j); // Respect the parent child relationship irrespective of package
        System.out.println(k); // Compilation error - private variable
        System.out.println(l); // Compilation Error - not accessible as it is in diff package

        FirstClass cls = new FirstClass();
        System.out.println(cls.i); // Accessible because it is public
        System.out.println(cls.j); // Compilation error
        // Private variable will not be accessible here also.
        System.out.println(cls.k); // Compilation error
        System.out.println(cls.l); // Compilation error

    }
} 
```

### 备忘单

*   `public`，`private`，`protected`是 3 种访问修饰符
*   Java 有 4 个访问级别。 **公开，私有，受保护 & 默认**。
*   一个类只能具有公开和默认访问级别。
*   方法和实例变量（**非本地**）可以使用所有 4 个访问级别。
*   如果某个类对其他类不可见，则即使该成员的访问级别是公开的，也没有访问该类成员的问题（**重要**）。
*   在成员可见之前，应检查类可见性。
*   如果超类具有公开成员，则子类将继承它，即使它在其他包中也是如此。
*   `this`始终引用当前正在执行的对象。
*   其他成员甚至可以从其他包中访问公开成员。
*   只能通过同一类中的代码访问私有成员。
*   默认成员对包外部的子类不可见。
*   即使在不同的包中，受保护的成员也可以被子类看到。
*   *受保护*与*默认*之间的不同之处在于，默认仅在包之外的子类的情况下才会显示。
*   局部变量*不能*具有*访问修饰符*。
*   局部变量只能具有可以应用的最终非访问修饰符。

<https://www.youtube.com/embed/WZRTwkCOYBQ?feature=oembed>

