开发者

In Java, why are class members accessible to members of the same package by default? [duplicate]

开发者 https://www.devze.com 2023-02-17 14:44 出处:网络
This question already has answers here: What is the default access specifier in Java? (12 answers) 开发者_StackOverflowClosed 8 years ago.
This question already has answers here: What is the default access specifier in Java? (12 answers) 开发者_StackOverflow Closed 8 years ago.

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?


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.


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.


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.


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


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


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消