In the examples so far, we have seen the use of the public and private keywords. These are access modifiers that control the visibility of fields, methods, and classes in the scope of the entire application. Why would we really worry about the visibility of these members? All this time, we have been talking about data hiding and encapsulation in object-oriented design. Defining visibility rules for the members helps achieve these goals. To explain how, let’s look at an example. Consider a situation where we are running an application in a Java applet downloaded from, say, www.mindstick.com, and at the same time we are purchasing this book from the Amazon website. Just imagine what would happen in this situation if there were no visibility restrictions provided in Java. In this case, the credit card information we input on the Amazon site may become visible to the game downloaded from the MindStick site.
Obviously, we won’t like this—there should be some mechanism that protects the visibility of the members of one application from another application. This mechanism in Java involves the creation of namespaces. When a Java runtime loads a class (an internal class called ClassLoader is responsible for this), it does so in a namespace, which is made unique depending on its origin. A namespace is a set of unique class names loaded by a particular ClassLoader; each class name is bound to a specific Class object. Thus, the classes loaded from the Amazon site would be put in a different namespace than the classes loaded from the Zapak site. This not only allows information hiding but also helps in avoiding name collisions; therefore, the classes belonging to two different namespaces can have the same name.
Many times, we will also want to control the member’s visibility within different parts of the same application. For example, the sensitive employee data should not be made visible to outsiders browsing the company website. Java provides this kind of security (or the access control of members) with the help of private, protected, public, and default modifiers.
Naturally, we need to define a namespace for achieving this kind of security. A namespace defines a boundary area within which access of a containing member is restricted. Java defines such namespaces by using the concept of package. Earlier, we used the Java packages java.util and java.awt. The members defined in the java.util package may be made available to other members within the same package and made inaccessible to members within the java.awt package. But who does this? When we create classes, our job is to create only appropriate logical packages in our application and define the desired visibility of each code member. The rest is taken care of by the JVM. So let’s discuss how to define this visibility. Four possible values control the visibility or the access level of the entities in our program.