Java 中的 public、protected、package-private 和 private 有什么区别?

发布于 2024-07-07 16:46:25 字数 165 浏览 15 评论 0原文

在 Java 中,是否有明确的规则规定何时使用每种访问修饰符,即默认(包私有)、publicprotectedprivate ,同时制作classinterface并处理继承?

In Java, are there clear rules on when to use each of access modifiers, namely the default (package private), public, protected and private, while making class and interface and dealing with inheritance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

云之铃。 2024-07-14 16:46:25

官方教程可能对您有一些用处。


包子
(相同的pkg)
子类
(不同的pkg)
世界
public✔️✔️✔️✔️✔️
protected✔️✔️✔️✔️
无修饰符✔️✔️✔️
私人✔️

✔️:可访问
❌:无法访问

The official tutorial may be of some use to you.


ClassPackageSubclass
(same pkg)
Subclass
(diff pkg)
World
public✔️✔️✔️✔️✔️
protected✔️✔️✔️✔️
no modifier✔️✔️✔️
private✔️

✔️: accessible
❌: not accessible

只怪假的太真实 2024-07-14 16:46:25

(警告:我不是 Java 程序员,我是 Perl 程序员。Perl 没有正式的保护,这也许就是为什么我这么了解这个问题:) )

Private

就像你想的那样,只有 class 在其中声明它可以看到它。

Package Private

它只能被声明它的看到和使用。 这是 Java 中的默认设置(有些人认为这是一个错误)。

受保护的

包 Private + 可以被子类或包成员看到。

公开

每个人都可以看到。

已发布

在我控制的代码之外可见。 (虽然不是 Java 语法,但对于本次讨论很重要)。

C++ 定义了一个称为“朋友”的附加级别,您对此了解得越少越好。

什么时候应该使用什么? 整个想法是封装以隐藏信息。 您希望尽可能向用户隐藏某些操作的细节。 为什么? 因为这样您就可以稍后更改它们而不会破坏任何人的代码。 这使您可以优化、重构、重新设计和修复错误,而不必担心有人正在使用您刚刚检修的代码。

因此,经验法则是让事物只在必要时可见。 从私有开始,仅根据需要添加更多可见性。 只公开用户需要知道的内容,公开的每个细节都会限制您重新设计系统的能力。

如果您希望用户能够自定义行为,而不是将内部公开以便他们可以覆盖它们,那么将这些内部内容推入对象并公开该接口通常是更好的主意。 这样他们就可以简单地插入一个新对象。 例如,如果您正在编写一个 CD 播放器并希望“查找有关此 CD 的信息”位可自定义,而不是公开这些方法,您可以将所有功能放入其对象中,并仅公开您的对象 getter/setter。 通过这种方式,吝啬地暴露你的内心会鼓励良好的构图和关注点的分离,

我坚持只使用“私人”和“公共”。 许多面向对象的语言都具备这一点。 “受保护”可能很方便,但它是一种欺骗。 一旦接口超出私有范围,它就超出了您的控制范围,您必须查看其他人的代码才能找到用途。

这就是“发布”的概念出现的地方。更改接口(重构它)要求您找到所有正在使用它的代码并对其进行更改。 如果接口是私有的,那就没问题了。 如果它受到保护,您必须找到所有子类。 如果它是公开的,您必须查找使用您的代码的所有代码。 有时这是可能的,例如,如果您正在编写仅供内部使用的公司代码,那么接口是否公开并不重要。 您可以从公司存储库中获取所有代码。 但如果一个接口被“发布”,如果有代码在你的控制范围之外使用它,那么你就完蛋了。 您必须支持该接口,否则就有破坏代码的风险。 即使受保护的接口也可以被认为是已发布的(这就是为什么我不关心受保护的接口)。

许多语言发现公共/受保护/私有的等级性质过于限制且不符合现实。 为此,出现了特质类别的概念,但那是另一回事了。

(Caveat: I am not a Java programmer, I am a Perl programmer. Perl has no formal protections which is perhaps why I understand the problem so well :) )

Private

Like you'd think, only the class in which it is declared can see it.

Package Private

It can only be seen and used by the package in which it was declared. This is the default in Java (which some see as a mistake).

Protected

Package Private + can be seen by subclasses or package members.

Public

Everyone can see it.

Published

Visible outside the code I control. (While not Java syntax, it is important for this discussion).

C++ defines an additional level called "friend" and the less you know about that the better.

When should you use what? The whole idea is encapsulation to hide information. As much as possible you want to hide the detail of how something is done from your users. Why? Because then you can change them later and not break anybody's code. This lets you optimize, refactor, redesign, and fix bugs without worrying that someone was using that code you just overhauled.

So, the rule of thumb is to make things only as visible as they have to be. Start with private and only add more visibility as needed. Only make public that which is necessary for the user to know, every detail you make public cramps your ability to redesign the system.

If you want users to be able to customize behaviors, rather than making internals public so they can override them, it's often a better idea to shove those guts into an object and make that interface public. That way they can simply plug in a new object. For example, if you were writing a CD player and wanted the "go find info about this CD" bit customizable, rather than make those methods public you'd put all that functionality into its object and make just your object getter/setter public. In this way being stingy about exposing your guts encourages good composition and separation of concerns

I stick with just "private" and "public". Many OO languages just have that. "Protected" can be handy, but it's a cheat. Once an interface is more than private it's outside of your control and you have to go looking in other people's code to find uses.

This is where the idea of "published" comes in. Changing an interface (refactoring it) requires that you find all the code which is using it and change that, too. If the interface is private, well no problem. If it's protected you have to go find all your subclasses. If it's public you have to go find all the code which uses your code. Sometimes this is possible, for example, if you're working on corporate code that's for internal use only it doesn't matter if an interface is public. You can grab all the code out of the corporate repository. But if an interface is "published", if there is code using it outside your control, then you're hosed. You must support that interface or risk breaking code. Even protected interfaces can be considered published (which is why I don't bother with protected).

Many languages find the hierarchical nature of public/protected/private to be too limiting and not in line with reality. To that end, there is the concept of a trait class, but that's another show.

最美不过初阳 2024-07-14 16:46:25

这是该表的更好版本,其中还包括模块列。

在此处输入图像描述


说明

  • 私有成员 (i)只能在与其相同的类中访问已声明。

  • 没有访问修饰符 (j) 的成员只能在同一包的类中访问。

  • 受保护成员 (k) 可在同一包中的所有类其他包的子类中访问。

  • public 成员 (l) 可供所有类访问(除非它驻留在 模块 不导出其声明的包)。


选择哪个修改器?

访问修饰符是一个帮助您防止意外破坏封装的工具(*)。 问问自己是否希望该成员成为类、包、类层次结构的内部成员或根本不是内部成员,并相应地选择访问级别。

示例:

  • 字段long internalCounter可能应该是私有的,因为它是可变的并且是实现细节。
  • 只应在工厂类(在同一包中)中实例化的类应该具有包限制的构造函数,因为不可能直接从包外部调用它。
  • 应该保护在渲染之前调用并用作子类中的挂钩的内部 void beforeRender() 方法。
  • 从 GUI 代码调用的 void saveGame(File dst) 方法应该是公共的。

(*) 封装到底是什么?

Here's a better version of the table, that also includes a column for modules.

enter image description here


Explanations

  • A private member (i) is only accessible within the same class as it is declared.

  • A member with no access modifier (j) is only accessible within classes in the same package.

  • A protected member (k) is accessible within all classes in the same package and within subclasses in other packages.

  • A public member (l) is accessible to all classes (unless it resides in a module that does not export the package it is declared in).


Which modifier to choose?

Access modifiers is a tool to help you to prevent accidentally breaking encapsulation(*). Ask yourself if you intend the member to be something that's internal to the class, package, class hierarchy or not internal at all, and choose access level accordingly.

Examples:

  • A field long internalCounter should probably be private since it's mutable and an implementation detail.
  • A class that should only be instantiated in a factory class (in the same package) should have a package restricted constructor, since it shouldn't be possible to call it directly from outside the package.
  • An internal void beforeRender() method called right before rendering and used as a hook in subclasses should be protected.
  • A void saveGame(File dst) method which is called from the GUI code should be public.

(*) What is Encapsulation exactly?

浪漫之都 2024-07-14 16:46:25
____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |
Modifier of x \ |               |           |               |
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘
____________________________________________________________________
____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |
Modifier of x \ |               |           |               |
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘
____________________________________________________________________
倒带 2024-07-14 16:46:25

简单的规则。 首先将所有内容声明为私有。 然后,随着需求的出现和设计的保证,向公众迈进。

当公开成员时,问问自己是公开表示选择还是抽象选择。 第一个是你要避免的,因为它会引入太多对实际表示而不是其可观察行为的依赖。

作为一般规则,我尝试避免通过子类化来覆盖方法实现; 逻辑太容易搞砸了。 如果您打算重写抽象受保护方法,请声明它。

另外,在重写时使用 @Override 注释,以防止重构时出现问题。

Easy rule. Start with declaring everything private. And then progress towards the public as the needs arise and design warrants it.

When exposing members ask yourself if you are exposing representation choices or abstraction choices. The first is something you want to avoid as it will introduce too many dependencies on the actual representation rather than on its observable behavior.

As a general rule I try to avoid overriding method implementations by subclassing; it's too easy to screw up the logic. Declare abstract protected methods if you intend for it to be overridden.

Also, use the @Override annotation when overriding to keep things from breaking when you refactor.

半透明的墙 2024-07-14 16:46:25

它实际上比简单的网格显示要复杂一些。 网格告诉您是否允许访问,但是访问到底是什么? 此外,访问级别以复杂的方式与嵌套类和继承交互。

“默认”访问(通过缺少关键字指定)也称为 package-private< /strong>。 例外:在接口中,没有修饰符意味着公共访问; 禁止使用除 public 之外的修饰符。 枚举常量始终是公共的。

摘要

是否允许使用此访问说明符访问成员?

  • 成员是私有:仅当成员与调用代码在同一类中定义时。
  • 成员是包私有的:仅当调用代码位于成员的直接封闭包内时。
  • 成员受保护:相同的包,或者如果成员是在包含调用代码的类的超类中定义的。
  • 成员是公共:是的。

适用于哪些访问说明符

局部变量和形式参数不能采用访问说明符。 由于根据范围规则,外部本质上无法访问它们,因此它们实际上是私有的。

对于顶级范围内的类,仅允许 public 和 package-private。 这种设计选择可能是因为 protectedprivate 在包级别上是多余的(没有包的继承)。

所有访问说明符都可以用于类成员(构造函数、方法和静态成员函数、嵌套类)。

相关:Java 类可访问性

顺序

访问说明符可以严格排序

公共> 受保护> 包私有> 私人

意味着 public 提供最多的访问权限,private 提供最少的访问权限。 私有成员上可能的任何引用也对包私有成员有效; 对包私有成员的任何引用在受保护成员上都有效,等等。 (将受保护成员的访问权授予同一包中的其他类被认为是一个错误。)

注释

  • 类的方法< em>允许访问同一类的其他对象的私有成员。更准确地说,类 C 的方法可以访问 C 的任何子类的对象上的 C 的私有成员。Java 不允许支持按实例限制访问,仅按类限制。 (与 Scala 相比,Scala 使用 private[this] 支持它。)
  • 您需要访问构造函数来构造对象。 因此,如果所有构造函数都是私有的,则该类只能由类内的代码(通常是静态工厂方法或静态变量初始值设定项)来构造。 对于包私有或受保护的构造函数也是如此。
    • 仅具有私有构造函数也意味着该类不能在外部进行子类化,因为 Java 要求子类的构造函数隐式或显式调用超类构造函数。 (但是,它可以包含一个子类化它的嵌套类。)

内部类

您还必须考虑嵌套范围,例如内部类。 复杂性的一个例子是内部类具有成员,这些成员本身可以采用访问修饰符。 所以你可以有一个带有公共成员的私有内部类; 会员可以访问吗? (见下文。)一般规则是查看范围并递归思考以查看是否可以访问每个级别。

但是,这非常复杂,有关完整详细信息, 查阅 Java 语言规范。 (是的,过去存在编译器错误。)

要了解它们如何交互,请考虑此示例。 有可能“泄漏”私有内部类; 这通常是一个警告:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

编译器输出:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

一些相关问题:

It's actually a bit more complicated than a simple grid shows. The grid tells you whether an access is allowed, but what exactly constitutes an access? Also, access levels interact with nested classes and inheritance in complex ways.

The "default" access (specified by the absence of a keyword) is also called package-private. Exception: in an interface, no modifier means public access; modifiers other than public are forbidden. Enum constants are always public.

Summary

Is an access to a member with this access specifier allowed?

  • Member is private: Only if member is defined within the same class as calling code.
  • Member is package private: Only if the calling code is within the member's immediately enclosing package.
  • Member is protected: Same package, or if member is defined in a superclass of the class containing the calling code.
  • Member is public: Yes.

What access specifiers apply to

Local variables and formal parameters cannot take access specifiers. Since they are inherently inaccessible to the outside according to scoping rules, they are effectively private.

For classes in the top scope, only public and package-private are permitted. This design choice is presumably because protected and private would be redundant at the package level (there is no inheritance of packages).

All the access specifiers are possible on class members (constructors, methods and static member functions, nested classes).

Related: Java Class Accessibility

Order

The access specifiers can be strictly ordered

public > protected > package-private > private

meaning that public provides the most access, private the least. Any reference possible on a private member is also valid for a package-private member; any reference to a package-private member is valid on a protected member, and so on. (Giving access to protected members to other classes in the same package was considered a mistake.)

Notes

  • A class's methods are allowed to access private members of other objects of the same class. More precisely, a method of class C can access private members of C on objects of any subclass of C. Java doesn't support restricting access by instance, only by class. (Compare with Scala, which does support it using private[this].)
  • You need access to a constructor to construct an object. Thus if all constructors are private, the class can only be constructed by code living within the class (typically static factory methods or static variable initializers). Similarly for package-private or protected constructors.
    • Only having private constructors also means that the class cannot be subclassed externally, since Java requires a subclass's constructors to implicitly or explicitly call a superclass constructor. (It can, however, contain a nested class that subclasses it.)

Inner classes

You also have to consider nested scopes, such as inner classes. An example of the complexity is that inner classes have members, which themselves can take access modifiers. So you can have a private inner class with a public member; can the member be accessed? (See below.) The general rule is to look at scope and think recursively to see whether you can access each level.

However, this is quite complicated, and for full details, consult the Java Language Specification. (Yes, there have been compiler bugs in the past.)

For a taste of how these interact, consider this example. It is possible to "leak" private inner classes; this is usually a warning:

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

Compiler output:

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

Some related questions:

爱她像谁 2024-07-14 16:46:25

根据经验:

  • private:类范围。
  • default(或package-private):包范围。
  • protected包范围+子(类似于包,但我们可以从不同的包中子类化它)。 protected 修饰符始终保持“父子”关系。
  • public:无处不在。

因此,如果我们将访问权限分为三个权限:

  • (D)irect(从同一类内的方法调用,或通过“this”语法调用)。
  • (R)引用(使用对类的引用或通过“点”语法调用方法)。
  • (I)继承(通过子类化)。

然后我们有这个简单的表:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+

As a rule of thumb:

  • private: class scope.
  • default (or package-private): package scope.
  • protected: package scope + child (like package, but we can subclass it from different packages). The protected modifier always keeps the "parent-child" relationship.
  • public: everywhere.

As a result, if we divide access right into three rights:

  • (D)irect (invoke from a method inside the same class, or via "this" syntax).
  • (R)eference (invoke a method using a reference to the class, or via "dot" syntax).
  • (I)nheritance (via subclassing).

then we have this simple table:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+
一杯敬自由 2024-07-14 16:46:25

简而言之

  • public:可从任何地方访问。
  • protected:可由同一包中的类以及驻留在任何包中的子类访问。
  • 默认(未指定修饰符):可由同一包的类访问。
  • private:只能在同一个类中访问。

In very short

  • public: accessible from everywhere.
  • protected: accessible by the classes of the same package and the subclasses residing in any package.
  • default (no modifier specified): accessible by the classes of the same package.
  • private: accessible within the same class only.
桃酥萝莉 2024-07-14 16:46:25

Java 中最容易被误解的访问修饰符是 protected。 我们知道它与默认修饰符类似,但有一个例外,子类可以看到它。 但如何呢? 下面是一个示例,希望能够澄清这种困惑:

  • 假设我们有 2 个类; FatherSon,每个都在自己的包中:

    包父包; 
    
      公开课父亲 
      { 
    
      } 
    
      ------------------------------------------- 
    
      包子包; 
    
      公开课儿子延伸父亲 
      { 
    
      } 
      
  • 让我们向 Father 添加一个受保护的方法 foo() >.

    包父包; 
    
      公开课父亲 
      { 
          受保护的 void foo(){} 
      } 
      
  • 方法 foo() 可以在 4 个上下文中调用:

    1. 位于定义 foo() 的同一包中的类 (fatherpackage) 中:

      包父包; 
      
        公开课 SomeClass 
        { 
            public void someMethod(父亲 f, 儿子 s) 
            { 
                f.foo(); 
                s.foo(); 
            } 
        } 
        
    2. 在子类内部,通过 thissuper 在当前实例上:

      包sonpackage; 
      
        公开课儿子延伸父亲 
        { 
            公共无效sonMethod() 
            { 
                this.foo(); 
                超级.foo(); 
            } 
        } 
        
    3. 在类型为同一类的引用上:

      包父包; 
      
        公开课父亲 
        { 
            公共无效fatherMethod(父亲f) 
            { 
                f.foo();   // 即使 foo() 是私有的也有效 
            } 
        } 
      
        ------------------------------------------- 
      
        包子包; 
      
        公开课儿子延伸父亲 
        { 
            公共无效sonMethod(Son s) 
            { 
                s.foo(); 
            } 
        } 
        
    4. 在类型为父类的引用上,并且位于定义 foo() 的包内部 (fatherpackage ) [这可以包含在上下文中。 1]:

      包父包; 
      
        公开课儿子延伸父亲 
        { 
            公共无效sonMethod(父亲f) 
            { 
                f.foo(); 
            } 
        } 
        
  • 以下情况无效。

    1. 在类型为父类的引用上,并且位于定义 foo() 的包外部 (fatherpackage ):

      包sonpackage; 
      
        公开课儿子延伸父亲 
        { 
            公共无效sonMethod(父亲f) 
            { 
                f.foo();   // 编译错误 
            } 
        } 
        
    2. 子类包内的非子类(子类从其父类继承受保护的成员,并使它们对非子类私有):

      包sonpackage; 
      
        公开课 SomeClass 
        { 
            public void someMethod(Son s) 抛出异常 
            { 
                s.foo();   // 编译错误 
            } 
        } 
        

The most misunderstood access modifier in Java is protected. We know that it's similar to the default modifier with one exception in which subclasses can see it. But how? Here is an example which hopefully clarifies the confusion:

  • Assume that we have 2 classes; Father and Son, each in its own package:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
    
  • Let's add a protected method foo() to Father.

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
    
  • The method foo() can be called in 4 contexts:

    1. Inside a class that is located in the same package where foo() is defined (fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
      
    2. Inside a subclass, on the current instance via this or super:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
      
    3. On an reference whose type is the same class:

      package fatherpackage;
      
      public class Father
      {
          public void fatherMethod(Father f)
          {
              f.foo(); // valid even if foo() is private
          }
      }
      
      -------------------------------------------
      
      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Son s)
          {
              s.foo();
          }
      }
      
    4. On an reference whose type is the parent class and it is inside the package where foo() is defined (fatherpackage) [This can be included inside context no. 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
      
  • The following situations are not valid.

    1. On an reference whose type is the parent class and it is outside the package where foo() is defined (fatherpackage):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
      
    2. A non-subclass inside a package of a subclass (A subclass inherits the protected members from its parent, and it makes them private to non-subclasses):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }
      
浅唱々樱花落 2024-07-14 16:46:25

私有

  • 方法、变量和构造函数

声明为私有的方法、变量和构造函数只能在声明的类本身内访问。

  • 类和接口

私有访问修饰符是最严格的访问级别。 类和接口不能是私有的。

注意

如果类中存在公共 getter 方法,则可以在类外部访问声明为私有的变量。
在超类中声明为 protected 的变量、方法和构造函数只能被其他包中的子类或受保护成员类的包中的任何类访问。


受保护

  • 类和接口

受保护的访问修饰符不能应用于类和接口。

方法、字段可以声明为受保护,但是方法接口中的字段不能声明为受保护。

注意

受保护的访问使子类有机会使用辅助方法或变量,同时防止尝试使用它的不相关类。


公共

声明为公共的类、方法、构造函数、接口等可以从任何其他类访问。​​

因此,在公共类中声明的字段、方法、块可以被 访问。可以从属于 Java 宇宙的任何类进行访问。

  • 不同的包

但是,如果我们尝试访问的公共类位于不同的包中,那么该公共类仍然需要导入。

由于类继承,类的所有公共方法和变量都会被其子类继承。


默认 - 无关键字:

默认访问修饰符意味着我们不会显式声明类、字段、方法等的访问修饰符。

  • 在同一包内

没有任何访问控制修饰符声明的变量或方法可用于同一包中的任何其他类。 接口中的字段是隐式公共静态最终的,并且接口中的方法默认是公共的。

注意

我们无法覆盖静态字段。如果您尝试覆盖它不会显示任何错误
但它不起作用,我们除外。

相关答案

参考链接

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol .html
http://www.tutorialspoint.com/java/java_access_modifiers.htm

Private

  • Methods,Variables and Constructors

Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself.

  • Class and Interface

Private access modifier is the most restrictive access level. Class and interfaces cannot be private.

Note

Variables that are declared private can be accessed outside the class if public getter methods are present in the class.
Variables, methods and constructors which are declared protected in a superclass can be accessed only by the subclasses in other package or any class within the package of the protected members' class.


Protected

  • Class and Interface

The protected access modifier cannot be applied to class and interfaces.

Methods, fields can be declared protected, however methods and fields in a interface cannot be declared protected.

Note

Protected access gives the subclass a chance to use the helper method or variable, while preventing a nonrelated class from trying to use it.


Public

A class, method, constructor, interface etc declared public can be accessed from any other class.

Therefore fields, methods, blocks declared inside a public class can be accessed from any class belonging to the Java Universe.

  • Different Packages

However if the public class we are trying to access is in a different package, then the public class still need to be imported.

Because of class inheritance, all public methods and variables of a class are inherited by its subclasses.


Default -No keyword:

Default access modifier means we do not explicitly declare an access modifier for a class, field, method, etc.

  • Within the same Packages

A variable or method declared without any access control modifier is available to any other class in the same package. The fields in an interface are implicitly public static final and the methods in an interface are by default public.

Note

We cannot Override the Static fields.if you try to override it does not show any error
but it doesnot work what we except.

Related Answers

References links

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
http://www.tutorialspoint.com/java/java_access_modifiers.htm

恋你朝朝暮暮 2024-07-14 16:46:25

Java 访问修饰符

在此处输入图像描述

访问修饰符可适用于 classfield[关于]方法。 尝试访问、子类化或覆盖它。

  • 字段方法的访问是通过进行的。
  • 继承和开闭原则[关于]
    • 后继(子类)访问修饰符可以是任意
    • 后继方法(覆盖)访问修饰符应该相同或扩展它

顶级类(第一级范围)可以是public默认嵌套类[About]可以包含其中任何一个

package 未申请包层次结构

[Swift 访问修饰符]

Java access modifiers

enter image description here

Access modifier can be applicable for class, field[About], method. Try to access, subclass or override this.

  • Access to field or method is through a class.
  • Inheritance and Open Closed Principle[About]
    • Successor class(subclass) access modifier can be any.
    • Successor method(override) access modifier should be the same or expand it

Top level class(first level scope) can be public and default. Nested class[About] can have any of them

package is not applying for package hierarchy

[Swift access modifiers]

不回头走下去 2024-07-14 16:46:25

差异可以在已经提供的链接中找到,但使用哪一个通常取决于“最少知识原则”。 只允许所需的最低可见度。

The difference can be found in the links already provided but which one to use usually comes down to the "Principle of Least Knowledge". Only allow the least visibility that is needed.

栀梦 2024-07-14 16:46:25

私有:仅对类进行有限访问

默认(无修饰符):对类和包进行有限访问

受保护:对类、包和子类进行有限访问(包内和包外)

Public:可供类、包(所有)和子类访问......简而言之,无处不在。

Private: Limited access to class only

Default (no modifier): Limited access to class and package

Protected: Limited access to class, package and subclasses (both inside and outside package)

Public: Accessible to class, package (all), and subclasses... In short, everywhere.

墨洒年华 2024-07-14 16:46:25

访问修饰符可以在多个级别上限制访问。

公共:它基本上就像您可以从任何类访问一样简单,无论它是否在同一个包中。

如果您在同一个包中,则可以直接访问,但如果您在另一个包中,则可以创建该类的对象。

默认:可以在同一包中从任何包类访问它。

要访问您可以创建该类的对象。 但您无法在包外部访问此变量。

受保护:您可以访问同一包中的变量以及任何其他包中的子类。
所以基本上它是默认+继承行为。

要访问基类中定义的受保护字段,您可以创建子类的对象。

私有:可以在同一类中访问。

在非静态方法中,您可以直接访问,因为 this 引用(也在构造函数中),但要在静态方法中访问,您需要创建类的对象。

Access modifiers are there to restrict access at several levels.

Public: It is basically as simple as you can access from any class whether that is in same package or not.

To access if you are in same package you can access directly, but if you are in another package then you can create an object of the class.

Default: It is accessible in the same package from any of the class of package.

To access you can create an object of the class. But you can not access this variable outside of the package.

Protected: you can access variables in same package as well as subclass in any other package.
so basically it is default + Inherited behavior.

To access protected field defined in base class you can create object of child class.

Private: it can be access in same class.

In non-static methods you can access directly because of this reference (also in constructors)but to access in static methods you need to create object of the class.

蓝梦月影 2024-07-14 16:46:25

Java 中的访问修饰符。

Java 访问修饰符用于在 Java 中提供访问控制。

1. 默认值:

只能访问同一包中的类。

例如,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

此访问权限比 public 和 protected 受到更多限制,但比 private 受到更少限制。

2. 公共

可以从任何地方访问。 (全球访问)

例如,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

输出:你好

3。 Private

只能在同一类内部访问。

如果您尝试在另一个类中访问一个类的私有成员,则会引发编译错误。 例如,

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4。 Protected

只能被同一个包中的类及其子类访问

例如,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

输出:你好

在此输入图像描述

Access modifiers in Java.

Java access modifiers are used to provide access control in Java.

1. Default:

Accessible to the classes in the same package only.

For example,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

This access is more restricted than public and protected, but less restricted than private.

2. Public

Can be accessed from anywhere. (Global Access)

For example,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

Output:Hello

3. Private

Accessible only inside the same class.

If you try to access private members on one class in another will throw compile error. For example,

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4. Protected

Accessible only to the classes in the same package and to the subclasses

For example,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

Output: Hello

Enter image description here

静水深流 2024-07-14 16:46:25

对包可见。 默认。 不需要修饰符。

仅对班级可见(私有)。

对全世界(公众)可见。

对包和所有子类可见(受保护)。

可以在不调用任何修饰符的情况下声明变量和方法。 默认示例:

String name = "john";

public int age(){
    return age;
}

私有访问修饰符 - private:

声明为私有的方法、变量和构造函数只能在声明的类本身内访问。 private 访问修饰符是限制性最强的访问级别。 类和接口不能是私有的。

如果类中存在公共 getter 方法,则可以在类外部访问声明为私有的变量。

使用 private 修饰符是对象封装自身并向外界隐藏数据的主要方式。

示例:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

公共访问修饰符 - public:

声明为 public 的类、方法、构造函数、接口等可以从任何其他类访问。 因此,在公共类中声明的字段、方法、块可以从属于 Java 世界的任何类访问。

但是,如果我们尝试访问的公共类位于不同的包中,则仍然需要导入该公共类。

由于类继承,类的所有公共方法和变量都被其子类继承。

示例:

public void cal(){

}

受保护的访问修饰符 - protected:

在超类中声明为 protected 的变量、方法和构造函数只能由另一个包中的子类或受保护成员类的包中的任何类访问。

protected 访问修饰符不能应用于类和接口。 方法、字段可以声明为 protected,但是接口中的方法和字段不能声明为 protected。

受保护的访问使子类有机会使用辅助方法或变量,同时防止不相关的类尝试使用它。

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

Visible to the package. The default. No modifiers are needed.

Visible to the class only (private).

Visible to the world (public).

Visible to the package and all subclasses (protected).

Variables and methods can be declared without any modifiers that are called. Default examples:

String name = "john";

public int age(){
    return age;
}

Private access modifier - private:

Methods, variables and constructors that are declared private can only be accessed within the declared class itself. The private access modifier is the most restrictive access level. Class and interfaces cannot be private.

Variables that are declared private can be accessed outside the class if public getter methods are present in the class.

Using the private modifier is the main way that an object encapsulates itself and hides data from the outside world.

Examples:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

Public access modifier - public:

A class, method, constructor, interface, etc. declared public can be accessed from any other class. Therefore fields, methods, blocks declared inside a public class can be accessed from any class belonging to the Java universe.

However, if the public class we are trying to access is in a different package, then the public class still need to be imported.

Because of class inheritance, all public methods and variables of a class are inherited by its subclasses.

Example:

public void cal(){

}

Protected access modifier - protected:

Variables, methods and constructors which are declared protected in a superclass can be accessed only by the subclasses in another package or any class within the package of the protected members' class.

The protected access modifier cannot be applied to class and interfaces. Methods, fields can be declared protected, however methods and fields in a interface cannot be declared protected.

Protected access gives the subclass a chance to use the helper method or variable, while preventing a nonrelated class from trying to use it.

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}
ペ泪落弦音 2024-07-14 16:46:25
  • public - 可从应用程序中的任何位置访问。

  • 默认 - 从包中访问。

  • 受保护 - 可从其他包中的包和子类访问。
    以及

  • private - 仅可从其类访问。

  • public - accessible from anywhere in the application.

  • default - accessible from package.

  • protected - accessible from package and sub-classes in other package.
    as well

  • private - accessible from its class only.

暖树树初阳… 2024-07-14 16:46:25

此页面很好地介绍了受保护的& 默认访问修饰符

....
受保护:受保护的访问修饰符有点棘手,您可以说它是默认访问修饰符的超集。 就同​​一包中的访问而言,受保护成员与默认成员相同。 不同之处在于,受保护的成员也可以被声明该成员的类的子类访问,这些子类位于父类所在的包之外。

但这些受保护的成员“只能通过继承在包外访问”。 即,您可以直接访问其他包中存在的子类中的类的受保护成员,就像该成员存在于子类本身中一样。 但是,在包外部的子类中,无法使用父类的引用来访问该受保护成员。
....

This page writes well about the protected & default access modifier

....
Protected: Protected access modifier is the a little tricky and you can say is a superset of the default access modifier. Protected members are same as the default members as far as the access in the same package is concerned. The difference is that, the protected members are also accessible to the subclasses of the class in which the member is declared which are outside the package in which the parent class is present.

But these protected members are “accessible outside the package only through inheritance“. i.e you can access a protected member of a class in its subclass present in some other package directly as if the member is present in the subclass itself. But that protected member will not be accessible in the subclass outside the package by using parent class’s reference.
....

我不咬妳我踢妳 2024-07-14 16:46:25

David 的答案提供了每个访问修饰符的含义。 至于何时使用每个类,我建议将所有供外部使用的类和每个类的方法(其 API)公开,并将其他所有内容公开。

随着时间的推移,您将了解何时将某些类设为包私有以及何时声明某些受保护的方法以在子类中使用。

David's answer provides the meaning of each access modifier. As for when to use each, I'd suggest making public all classes and the methods of each class that are meant for external use (its API), and everything else private.

Over time you'll develop a sense for when to make some classes package-private and when to declare certain methods protected for use in subclasses.

如果没有 2024-07-14 16:46:25

公共之间的差异、私有、默认和受保护的访问修饰符

这张图片将使您轻松了解公共、私有、受保护和默认访问修饰符之间的基本区别。 当您未在代码中声明 ant 访问修饰符时,默认修饰符会自动发生。

Differences between public, private, default and protected access modifiers

This image will make you understand easily about the basic differences between public, private, protected and default access modifiers. The default modifier takes place automatically when you don't declare ant access modifiers in your code.

意中人 2024-07-14 16:46:25

Public Protected Default 和 private 是访问修饰符。

它们用于封装或隐藏和显示类的内容。

  1. 类可以是公共的或默认的
  2. 类成员可以是公共的、受保护的、默认的或私有的。

private 在类外不可访问
默认值只能在包中访问。
在包以及扩展它的任何类中受到保护。
公众对所有人开放。

通常,成员变量被定义为私有的,但成员方法是公共的。

Public Protected Default and private are access modifiers.

They are meant for encapsulation, or hiding and showing contents of the class.

  1. Class can be public or default
  2. Class members can be public, protected, default or private.

Private is not accessible outside the class
Default is accessible only in the package.
Protected in package as well as any class which extends it.
Public is open for all.

Normally, member variables are defined private, but member methods are public.

薄荷梦 2024-07-14 16:46:25

注意:这只是对已接受答案的补充

这与 Java 访问修饰符

来自 Java 访问修饰符

Java 访问修饰符指定哪些类可以访问给定的
类及其字段、构造函数和方法。 访问修饰符可以
为类、其构造函数、字段和
方法。 Java访问修饰符有时也会在日常中被提及
语音为 Java 访问说明符,但正确的名称是 Java 访问
修饰符。 类、字段、构造函数和方法可以具有以下之一
四种不同的 Java 访问修饰符:

  • 列出项目
  • 私人
  • 默认(包)
  • 受保护
  • 公开

From 控制访问班级成员教程:

访问级别修饰符决定其他类是否可以使用
特定字段或调用特定方法。 有两个级别
访问控制:

  • 在顶层 - 公共或包私有(无显式修饰符)。
  • 在成员级别 - 公共、私有、受保护或包私有(无显式修饰符)。

可以使用修饰符 public 来声明类,在这种情况下
类对任何地方的所有类都是可见的。 如果一个类没有修饰符
(默认,也称为package-private),仅可见
在自己的包中

下表显示了每个成员所允许的访问权限
修饰符。

<预><代码>╔═════════════╦═══════╦═════════╦═════ ═════╦ ═══════╗
║ 修饰符 ║ 类 ║ 包 ║ 子类 ║ 世界 ║
╠═════════════╬═══════╬═════════╬═══════ ═══╬══════ ═╣
║ 公共 ║ Y ║ Y ║ Y ║ Y ║
║ 受保护 ║ Y ║ Y ║ Y ║ N ║
║ 无修饰符 ║ Y ║ Y ║ N ║ N ║
║ 私人 ║ Y ║ N ║ N ║ N ║
╚═════════════╩═══════╩═════════╩═══════ ═══╩══════ ═╝

第一个数据列表示类本身是否有权访问
由访问级别定义的成员。 正如你所看到的,一个类总是
可以访问自己的成员。 第二列表示是否
与该类位于同一包中的类(无论它们的
出身)有权访问该成员。 第三列表示
在此包之外声明的类的子类是否具有
访问会员。 第四列表示是否所有类
有权访问该会员。

访问级别以两种方式影响您。 首先,当您使用以下类时
来自另一个来源,例如Java平台中的类,
访问级别决定了您自己的这些类的哪些成员
类可以使用。 其次,当你写一个类时,你需要决定
类中每个成员变量和每个方法的访问级别是什么
应该有。

Note: This is just a supplement for the accepted answer.

This is related to Java Access Modifiers.

From Java Access Modifiers:

A Java access modifier specifies which classes can access a given
class and its fields, constructors and methods. Access modifiers can
be specified separately for a class, its constructors, fields and
methods. Java access modifiers are also sometimes referred to in daily
speech as Java access specifiers, but the correct name is Java access
modifiers. Classes, fields, constructors and methods can have one of
four different Java access modifiers:

  • List item
  • private
  • default (package)
  • protected
  • public

From Controlling Access to Members of a Class tutorials:

Access level modifiers determine whether other classes can use a
particular field or invoke a particular method. There are two levels
of access control:

  • At the top level—public, or package-private (no explicit modifier).
  • At the member level—public, private, protected, or package-private (no explicit modifier).

A class may be declared with the modifier public, in which case that
class is visible to all classes everywhere. If a class has no modifier
(the default, also known as package-private), it is visible only
within its own package

The following table shows the access to members permitted by each
modifier.

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ Modifier    ║ Class ║ Package ║ Subclass ║ World ║
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
║ public      ║ Y     ║ Y       ║ Y        ║ Y     ║
║ protected   ║ Y     ║ Y       ║ Y        ║ N     ║
║ no modifier ║ Y     ║ Y       ║ N        ║ N     ║
║ private     ║ Y     ║ N       ║ N        ║ N     ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

The first data column indicates whether the class itself has access to
the member defined by the access level. As you can see, a class always
has access to its own members. The second column indicates whether
classes in the same package as the class (regardless of their
parentage) have access to the member. The third column indicates
whether subclasses of the class declared outside this package have
access to the member. The fourth column indicates whether all classes
have access to the member.

Access levels affect you in two ways. First, when you use classes that
come from another source, such as the classes in the Java platform,
access levels determine which members of those classes your own
classes can use. Second, when you write a class, you need to decide
what access level every member variable and every method in your class
should have.

余生一个溪 2024-07-14 16:46:25

我常常意识到,通过创建现实世界的类比,可以记住任何语言的基本概念。 以下是我理解 Java 中的访问修饰符的类比:

假设您是一名大学学生,并且您有一位朋友周末来看望您。 假设校园中央有一尊大学创始人的巨大雕像。

  • 当你带他到校园时,你和你的朋友首先看到的就是这座雕像。 这意味着任何走进校园的人都可以在未经大学许可的情况下观看这座雕像。 这使得雕像公开

  • 接下来,您想带您的朋友去宿舍,但为此您需要将他注册为访客。 这意味着他获得了进入校园的通行证(与您的相同),可以进入校园的各个建筑物。 这将使他的门禁卡成为受保护

  • 您的朋友想要登录校园 WiFi,但没有任何凭据。 他上网的唯一方法是您与他共享您的登录信息。 (请记住,每个上大学的学生也拥有这些登录凭据)。 这将使您的登录凭据成为NO MODIFIER

  • 最后,您的朋友想阅读您发布在网站上的学期进度报告。 然而,每个学生都有自己的个人登录名来访问校园网站的这一部分。 这将使这些凭据成为私人

希望这可以帮助!

Often times I've realized that remembering the basic concepts of any language can made possible by creating real-world analogies. Here is my analogy for understanding access modifiers in Java:

Let's assume that you're a student at a university and you have a friend who's coming to visit you over the weekend. Suppose there exists a big statue of the university's founder in the middle of the campus.

  • When you bring him to the campus, the first thing that you and your friend sees is this statue. This means that anyone who walks in the campus can look at the statue without the university's permission. This makes the statue as PUBLIC.

  • Next, you want to take your friend to your dorm, but for that you need to register him as a visitor. This means that he gets an access pass (which is the same as yours) to get into various buildings on campus. This would make his access card as PROTECTED.

  • Your friend wants to login to the campus WiFi but doesn't have the any credentials to do so. The only way he can get online is if you share your login with him. (Remember, every student who goes to the university also possesses these login credentials). This would make your login credentials as NO MODIFIER.

  • Finally, your friend wants to read your progress report for the semester which is posted on the website. However, every student has their own personal login to access this section of the campus website. This would make these credentials as PRIVATE.

Hope this helps!

ˇ宁静的妩媚 2024-07-14 16:46:25

当您考虑访问修饰符时,只需这样考虑(适用于变量方法):

public --> 从任何地方都可以访问
私有 --> 只能在声明它的同一个类中访问

时,就会出现混乱

现在,当涉及到 defaultprotected default --> 。 不存在访问修饰符关键字。 这意味着它严格在类的包内可用。 在该包之外无处可以访问它。

受保护 --> 比默认值稍微宽松一些,除了相同的包类之外,它可以被声明的包外部的子类访问。

When you are thinking of access modifiers just think of it in this way (applies to both variables and methods):

public --> accessible from every where
private --> accessible only within the same class where it is declared

Now the confusion arises when it comes to default and protected

default --> No access modifier keyword is present. This means it is available strictly within the package of the class. Nowhere outside that package it can be accessed.

protected --> Slightly less stricter than default and apart from the same package classes it can be accessed by sub classes outside the package it is declared.

笔落惊风雨 2024-07-14 16:46:25

这都是关于封装(或者正如 Joe Phillips 所说,最少知识)。

从限制性最强的(私有的)开始,然后看看是否需要限制性较小的修饰符。

我们都使用方法和成员修饰符,例如 private、public 等,但是很少有开发人员做的一件事是使用包来逻辑地组织代码。

例如:
您可以将敏感的安全方法放入“安全”包中。
然后放置一个公共类来访问此包中的一些安全相关代码,但将其他安全类保持为包私有
因此,其他开发人员只能从该包外部使用公开可用的类(除非他们更改修饰符)。
这不是一项安全功能,但会指导使用。

Outside world -> Package (SecurityEntryClass ---> Package private classes)

另一件事是,相互依赖较多的类最终可能会出现在同一个包中,如果依赖关系太强,最终可能会被重构或合并。

相反,如果您将所有内容设置为 public ,则不清楚应该或不应该访问哪些内容,这可能会导致编写大量 javadoc (它不会通过编译器强制执行任何内容... )。

It is all about encapsulation (or as Joe Phillips stated, least knowledge).

Start with the most restrictive (private) and see if you need less restrictive modifiers later on.

We all use method and member modifiers like private, public, ... but one thing too few developers do is use packages to organize code logically.

For example:
You may put sensitive security methods in a 'security' package.
Then put a public class which accesses some of the security related code in this package but keep other security classes package private.
Thus other developers will only be able to use the publicly available class from outside of this package (unless they change the modifier).
This is not a security feature, but will guide usage.

Outside world -> Package (SecurityEntryClass ---> Package private classes)

Another thing is that classes which depend a lot on each other may end up in the same package and could eventually be refactored or merged if the dependency is too strong.

If on the contrary you set everything as public it will not be clear what should or should not be accessed, which may lead to writing a lot of javadoc (which does not enforce anything via the compiler...).

装纯掩盖桑 2024-07-14 16:46:25

我的两分钱:)

私有:

类 -> 顶级类不能是私有的。 内部类可以是私有的,可以从同一个类访问。

实例变量 -> 只能在类中访问。 无法访问班级外。

包私有:

类 -> 顶级类可以是包私有的。 它只能从同一个包中访问。 不是来自子包,也不是来自外部包。

实例变量 -> 可从同一包访问。 不是来自子包,也不是来自外部包。

受保护:

类 -> 顶级类无法受到保护。

实例变量 -> 只能在同一个包或子包中访问。 扩展类时只能在包外访问。

public:

类 -> 可从包/子包/另一个包访问

实例变量 -> 可从包/子包/另一个包访问

这里是详细答案

https://github.com/ junto06/java-4-beginners/blob/master/basics/access-modifier.md

My two cents :)

private:

class -> a top level class cannot be private. inner classes can be private which are accessible from same class.

instance variable -> accessible only in the class. Cannot access outside the class.

package-private:

class -> a top level class can be package-private. It can only be accessible from same package. Not from sub package, not from outside package.

instance variable -> accessible from same package. Not from sub package, not from outside package.

protected:

class -> a top level class cannot be protected.

instance variable -> Only accessible in same package or subpackage. Can only be access outside the package while extending class.

public:

class -> accessible from package/subpackage/another package

instance variable -> accessible from package/subpackage/another package

Here is detailed answer

https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md

回心转意 2024-07-14 16:46:25
  1. 公共:用于跨代码库和不同环境的广泛访问
    包。 适合您想要普遍公开的类和方法。
  2. 受保护:在同一包和子类中提供访问,甚至在不同的包中也是如此。 对于平衡封装与子类访问很有用。
  3. 默认(包私有):没有显式修饰符; 在同一个包内可以访问。 提供封装,同时允许在包内进行访问。
  4. 私有:限制对类内的访问。 非常适合向其他类隐藏实现细节。

继承:

类:

  1. public:可由任何类子类化。
  2. 受保护:可在同一包和不同包中进行子类化。
  3. 默认值:可在同一包中进行子类化。
  4. 私有:不可子类化。

方法和字段:

  1. public: 可随处访问。
  2. 受保护:可在同一包和子类中访问。
  3. 默认:可在同一包中访问。
  4. 私有:只能在同一类中访问。

对于重写的方法或字段,子类不能比其超类具有更严格的访问权限。

  1. public: Use for wide accessibility across your codebase and in different
    packages. Suitable for classes and methods you want to expose universally.
  2. protected: Provides access within the same package and in subclasses, even in different packages. Useful for balancing encapsulation with subclass access.
  3. Default (Package Private): No explicit modifier; accessible within the same package. Offers encapsulation while allowing access within a package.
  4. private: Restricts access to within the class. Ideal for hiding implementation details from other classes.

Inheritance:

Classes:

  1. public: Subclassable by any class.
  2. protected: Subclassable within the same package and in different packages.
  3. Default: Subclassable within the same package.
  4. private: Not subclassable.

Methods and Fields:

  1. public: Accessible everywhere.
  2. protected: Accessible within the same package and in subclasses.
  3. Default: Accessible within the same package.
  4. private: Accessible only within the same class.

Subclasses can't have more restrictive access than their superclasses for overridden methods or fields.

池木 2024-07-14 16:46:25

简单地说,它是类的对象变量或方法的范围。

如果您希望您的类变量甚至可以被其他包/文件夹访问,请使用Public

如果您不希望其他包/文件夹访问您的类的变量,请使用Protected

如果您不希望其他包/文件夹访问您的类的变量,并且您不希望您的类的子类访问它们,但您仍然希望它们可以在包中访问,请使用无修饰符。 (也称为“Package-Private”)

如果您不希望其他包/文件夹访问您的类的变量并且您不希望您的类的子类访问它们,并且您不希望使用 Private希望它们可以在包中的其他任何地方访问。

![在此输入图像描述

It is the scope of a Class's Object variables or methods simply put.

Use Public if you want your Class variables to be accessible by even other packages/folders!

Use Protected if okay you don't want other packages/folders accessing your Class's variables.

Use No Modifer if you don't want other packages/folders accessing your Class's variables and you don't want your Class's subclasses to access them, but you still want them accessible in the package. (Also called "Package-Private")

Use Private if you don't want other packages/folders accessing your Class's variables and you don't want your Class's subclasses to access them, and you don't want them accessible anywhere else in the package.

![enter image description here

变身佩奇 2024-07-14 16:46:25
  • public

如果一个类成员被声明为 public 那么它可以从任何

  • 受保护

    的 地方访问

    如果使用关键字 protected 声明类成员,则可以从同一类成员、同一包内的外部类成员以及继承的类成员访问该类成员。 如果类成员受到保护,则不能从外部包类访问它,除非继承外部包类,即扩展其他包超类。 但是受保护的类成员始终可用于相同的包类,无论是否继承相同的包类都没有关系

  • default

    在 Java 中,default 不是访问修饰符关键字。 如果声明类成员时没有任何访问修饰符关键字,则它被视为默认成员。 默认类成员始终可供同一包类成员使用。 但是外部包类成员不能访问默认类成员,即使外部类是子类,与受保护的成员不同

  • private

如果使用关键字 protected 声明类成员,那么在这种情况下,它仅对相同的类成员可用

  • public

If a class member is declared to be public then it can be accessed from anywhere

  • protected

    If a class member is declared with keyword protected, it can be accessed from the same class members, outside class members within the same package, and inherited class members. If a class member is protected then it can NOT be accessed from an outside package class unless the outside packaged class is inherited i.e. extends the other package superclass. But a protected class member is always available to the same package classes it does NOT matter whether the same package class is inherited or NOT

  • default

    In Java default is NOT an access modifier keyword. If a class member is declared without any access modifier keyword, it is considered a default member. The default class member is always available to the same package class members. But outside package class members can NOT access default class members even if outside classes are subclasses unlike protected members

  • private

If a class member is declared with keyword protected then in this case it is available ONLY to the same class members

咋地 2024-07-14 16:46:25

对于初学者来说,考虑这个例子可能会有所帮助;

考虑一下我在 foo 包中开发了 MyClass,它有一个名为 print 的奇妙方法,您有兴趣调用它(它可能是一个methodproperty):

package foo;  // I am in foo
public class MyClass {
     private void print() { //This is private
        System.out.println("I can print!");
    }
}

您已经在 bar 包中开发了 YourClass,并且您有兴趣使用 MyClass#print

package bar; \\You are not in same package as me
import foo.MyClass;
public class YourClass {
    void test() {
        MyClass myClass = new MyClass();
        myClass.print();
    }
}

你的代码未编译,出现错误 The method print() is undefined for the type MyClass

你来找我:

  • 你:我想使用你的方法,但它是私有。 您可以将其公开吗?
  • 我:不,我不想让其他人使用它。
  • 你:我是你的朋友,至少让我而不是其他人使用它。
  • 我:好的,我将删除 private 关键字。 我的访问修饰符将是 defaultprivate package。 既然你是我的朋友,你就必须和我在同一个包裹里。 所以你必须来我的包foo。 我的意思是确切的包,甚至不是子包。

那么 MyClass 将是

package foo;
public class MyClass {
    void print() { // No access modifier means default or package-private
        System.out.println("I can print!");
    }
}

YourClass 将是:

package foo;//You come to my package
public class YourClass {
    void test() {
        MyClass myClass = new MyClass();
        myClass.print();
    }
}

现在考虑一下:你再次来找我

  • 你:我的老板告诉我我不能改变我的包裹(在现实世界中,你无法更改您的包以使用其他类方法)
  • 我:还有另一种方法,如果您扩展我并且我使print()受保护 ,那么无论你是否更换套餐都可以使用。 (所以子类化总是让你可以访问我的方法)。

这是MyClass

package foo;
protected class MyClass { // It is now protected
     protected void print() {
        System.out.println("I can print!");
    }
}

这是YourClass

package bar; // You are on your own package
import foo.MyClass;

public class YourClass extends MyClass {
    void  test() {
        // You initiate yourself! But as you extend me, you can call my print()
        YourClass yourClass = new YourClass();
        yourClass.print();
    }
}

您可能已经注意到,通过使方法受保护,所有其他类都可以通过扩展<来使用它/code> 它,并且您无法轻松控制它的使用方式。 这个问题在 Java 17 中通过引入 sealed允许字词。 因此,您可以定义哪些可以扩展您。 通过类似 public seal class MyClass 允许 YourClass
请参阅Java 17 中的密封类是什么? 了解更多信息。

For beginners, considering this example can be helpful;

Consider I have developed MyClass in the foo package and it has a fantastic method named print which you are interested in calling it (it could be a method or property):

package foo;  // I am in foo
public class MyClass {
     private void print() { //This is private
        System.out.println("I can print!");
    }
}

You have developed YourClass in bar package, and you are interested to use MyClass#print

package bar; \\You are not in same package as me
import foo.MyClass;
public class YourClass {
    void test() {
        MyClass myClass = new MyClass();
        myClass.print();
    }
}

Your code is not compile and you get error The method print() is undefined for the type MyClass

You come to me:

  • You: I want to use your method but it is private. Can you make it public?
  • Me : No I don't want others use it
  • You: I am your friend at least let me not others use it.
  • Me : Ok I will remove the private keyword. My Access modifier will be default or private package. As you are my friend you must be in same package as me. So you must come to my package foo. I mean exact package not even a sub package.

Then MyClass will be

package foo;
public class MyClass {
    void print() { // No access modifier means default or package-private
        System.out.println("I can print!");
    }
}

YourClass will be:

package foo;//You come to my package
public class YourClass {
    void test() {
        MyClass myClass = new MyClass();
        myClass.print();
    }
}

Now consider this: Again you come to me

  • You: My boss told me I can not change my package (in the actual world, you can not change your package to use other classes methods)
  • Me : There is another way, if you extend me and I make print() protected, then you can use it whether you change you package or not. (So subclassing will always give you access to my method).

Here is MyClass

package foo;
protected class MyClass { // It is now protected
     protected void print() {
        System.out.println("I can print!");
    }
}

Here is YourClass:

package bar; // You are on your own package
import foo.MyClass;

public class YourClass extends MyClass {
    void  test() {
        // You initiate yourself! But as you extend me, you can call my print()
        YourClass yourClass = new YourClass();
        yourClass.print();
    }
}

You may have noticed that by making a method protected all other classes can use it by extending it, and you can not easily control how it can be used. This was solved in Java 17 by introducing sealed and permits words. So you can define which classes can extend you. By something like public sealed class MyClass permits YourClass
See What are sealed classes in Java 17? for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文