在Java中,为什么类成员默认可以被同一个包的成员访问?

发布于 2024-10-24 12:46:10 字数 142 浏览 7 评论 0原文

据我了解,与 C++ 不同,如果在声明数据成员时不指定“public”或“private”,则可以从同一包中的任何位置访问它。

Java 语言的设计者本可以选择相反的做法,但他们更喜欢默认将类成员设为公共(在同一包中)。

知道为什么吗?

I understand that unlike in C++, if I don't specify "public" or "private" when declaring a data member, it can be accessed from anywhere in the same package.

The designers of the Java language could have chosen the opposite, but instead they preferred to make class members public (in the same package) by default.

Any idea why?

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

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

发布评论

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

评论(7

记忆で 2024-10-31 12:46:10

它们不是公开的,同一包的成员可以访问它们。 Java 的精神是,给定的包代表一组连贯的协作职责,因此默认情况下它们应该能够互操作。

如果您希望强制实施不同的语义,则始终可以使用特定的访问级别。

They're not public, they're accessible to members of the same package. The Java ethos is that a given package represents a coherent set of coperating responsibilities, so by default they should be able to interoperate.

You can always use a specific access level if you wish to enforce differnt semantics.

当爱已成负担 2024-10-31 12:46:10

Java 中的默认可见性是包私有的。这意味着如果来自同一包,您可以访问这些实体。我不知道你为什么认为默认可见性是公开的。

The default visibility in Java is package-private. This means you can access those entities if from the same package. I don't know why you think the default visibility is public.

謸气贵蔟 2024-10-31 12:46:10

我不知道 Sun 发明 Java 时的决定,但恕我直言,这是因为您需要包私有类型的次数远多于私有或公共类。

例如,如果您在 org.example.myapi.* 中创建一个 API,您将尝试从外部调用您的 API,以便需要尽可能少的类来保持简单,以及让 API 执行所需的所有辅助类他们应该看到的,不应该被外界看到的。大多数时候,您需要更多的包私有 API 帮助器类,然后是公共 API 调用类。

I don't know the decision behind from sun as they invented java, but IMHO its because you need package-private types far more often then private or public classes.

For example, if you create a API in org.example.myapi.* you will try to have the calls to your API from outside to need as few classes as possible to keep thinks simple and all helper classes you need to let the API do what they should, should not be seen from outside. Most of the times you need more package-private API helper classes then public API call classes.

牛↙奶布丁 2024-10-31 12:46:10

@anOOb 在评论中写下了这一点……它值得得到彻底的回应。

当 Java 允许我从不同类(在单独的文件中)设置一个类的数据成员时,我感到非常惊喜,因为我不必经历创建访问器的麻烦。这样更方便,但不违反 OO 的原则之一吗?


它实际上比OO更深。这个原理就是数据封装的原理,同样适用于非OO设计。

访问器和修改器的主要目的是封装状态;即防止类的实现细节在类外部可见。这样做有两个主要原因:

  • 如果您控制或阻止对其内部状态的访问,则可以简化对类行为的推理。
  • 它使得更改状态变量的实现类型和不变量变得更加容易。如果使用类的代码仅使用访问器/修改器(即 getter/setter)来访问对象状态,那么您通常可以对类状态表示形式和不变量进行更改,同时对调用者隐藏更改的影响;例如,这是一个简单的例子

    私有 int 计数器;
    公共 int getCounter() { 返回计数器; }
    

    变成了

    私人长计数器;
    公共 int getCounter() { return (int)counter; }
    公共长 getLongCounter() { 返回计数器; }
    

我们在 Java 中使用访问器/修改器还有两个原因:

  • 访问器或修改器方法的行为通常可以在子类中重写。相比之下,在 Java 中,您无法覆盖甚至更改公开属性的可见性。

  • 有很多框架/工具依赖于您的类,它们具有遵循 JavaBeans 规范约定的方法名称/签名的访问器和修改器。

还应该注意的是,简单的 getter 和 setter 方法是由 JIT 编译器内联的,因此对性能的影响最小。


您不应该将创建访问器视为您应该尽力避免的“麻烦”。事实上,访问器(和修改器)是编写高质量 Java 代码的重要组成部分。这被认为是“最佳实践”,典型的样式/错误检查程序会将暴露的状态变量标记为问题。

@anOOb wrote this in a comment ... and it deserves a thorough response.

I was pleasantly surprised when Java let me set a data member of one class from a difference class (in a separate file), since I didn't have to go through the hassle of creating an accessor. It's more convenient but isn't against one of the principles of OO?


It is actually deeper than OO. The principle is the principle of data encapsulation, and it applies to non-OO design as well.

The primary aim of accessors and mutators is to encapsulate the state; i.e. to prevent implementation details of a class from being visible outside of the class. There are two main reasons for doing this:

  • It simplifies reasoning about the behavior of a class if you control or prevent access to its internal state.
  • It makes it easier to change the implementation type and invariants of a state variable. If the code that uses a class only uses accessors / mutators (i.e. getters / setters) to access the object state, then you can often make changes to the classes state representation and invariants while hiding the effects of the changes from the callers; e.g. here's a trivial example

    private int counter;
    public int getCounter() { return counter; }
    

    becomes

    private long counter;
    public int getCounter() { return (int)counter; }
    public long getLongCounter() { return counter; }
    

There are two more reasons we use accessors / mutators in Java:

  • An accessor or mutator method's behavior can typically be overridden in a subclass. By contrast, in Java you can't override or even change the visibility of an exposed attribute.

  • There are lots of frameworks / tools that depend on your classes having accessors and mutators with method names / signatures that follow the conventions of the JavaBeans spec.

It should also be noted that simple getter and setter methods are inlined by the JIT compiler, and therefore have minimal performance impact.


You should not think of creating accessors as a "hassle" that you should try to avoid. In fact, accessors (and mutators) are an important part of writing good quality Java code. This is considered to be "best practice", and typical style / bug checker programs will flag exposed state variables as problems.

征﹌骨岁月お 2024-10-31 12:46:10

仅供参考:

访问级别

--------------------------------------------------
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

Just for reference:

Access Levels

--------------------------------------------------
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
拿命拼未来 2024-10-31 12:46:10

我只想说,如果他们将默认访问级别设置为private,那就更好了。正如其他人指出的那样,这个想法可能是 package 访问级别将是最常用的访问级别,因为包“代表一组连贯的合作职责”(Visage)。然而,事实证明 private 是最常用的访问级别。

IMO,如果 Java 设计者有时间机器,他们会更改规范,使 private 成为默认访问级别。

I'd simply say that it would have been better if they made the default access level private. The idea was probably, as others note, that package access level would be the most frequently used access level because packages "represent a coherent set of cooperating responsibilities" (Visage). However, it turned out that private is the most frequently used access level.

IMO, the Java designers would change the spec to make private the default access level if they had a timemachine.

盛夏尉蓝 2024-10-31 12:46:10

你的假设是错误的;默认情况下,字段是公开的。下表描述了 Java 中的所有可见性级别:

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

更多信息请参见:http:// /download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Your assumption is wrong; fields are not public by default. The table below describes all visibility levels in Java:

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

More info here: http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

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