Interplay between visibility of class and fields
I learned that a class can be either public or package-private (the last value is the default one). A field of a class also can be either public or package-private. These "statuses" have the same meaning. If something is package-private it is visible only within the same package. It is public it is visible from everywhere (from any package).
What is not clear to me is how these statuses interplay. In particular I have interest in the following two cases:
The class is public but its field is package private. Will be this field visible only from within the package?
The class is package-private and it has a public field. Where will be sing this field?
In general I do not u开发者_JAVA百科nderstand why we bother if a class is public or package-private if, in any case, for any individual component of a class (field and methods) we indicate if it is public or package-private.
The most restrictive visibility applies. The answers to your questions are:
- Yes.
- Package only.
public fields in package classes usually don't make much sense.
There are some subtleties: a private field in a private nested class can be read by the enclosing class (though this causes some performance loss due to the implicit addition of synthetic accessors).
There's a short note on visibility in Sun's tutorial. Also refer to the section on nested classes.
Edit: For your interest, reflection also allows to tamper with visibilities.
If the class is public then all members of the class are 'potentially' visible. But as you say, the field will only be visible within the package.
If the class is not visible then how will you reference the field? So yes it will be restricted to the package only.
Of course it is worth noting that most of the time you shouldn't be using public fields unless they're constants.
I didn't understand your final point when I first read it, but I think you're asking why it is worth setting a restrictive class access modifier when you can just restrict access to the methods. One reason why you cannot rely on the fields/methods to provide the restriction is that an extending class (potentially in another package) may increase the visibility of the method. But if they cannot see the class to extend it then you're safe(r).
You can think of the the visibility as a hierarchy. You must be allowed to see the class before you can see any of its members or functions. With that in mind, your two scenarios resolve as:
- Yes, a class within the same package can see package private fields in a public class.
- Only classes in the same package can see public members and functions in a package private class.
If you are writing APIs that you expect others to use, it's a good idea to use package private to hide classes that are around to help with your design, but do not contribute to the API.
精彩评论