As you know, encapsulation links data with the code that manipulates it. However, encapsulation provides another important attribute: access control. Through encapsulation, you can control what parts of a program can access the members of a class. By controlling access, you can prevent misuse. For example, allowing access to data only through a well-defined set of methods, you can prevent the misuse of that data. Thus, when correctly implemented, a class creates a "black box" which may be used, but the inner workings of which are not open to tampering.
How a member can be accessed is determined by the access specifier that modifies its declaration. Java supplies a rich set of access specifiers. Some aspects of access control are related mostly to inheritance or packages.
Java's access specifiers are public, private and protected. Java also defines a default access level. protected applies only when inheritance is involved. So with the public and private, when a member of a class is modified by the public specifier, then that member can be accessed by any other code. When a member of a class is specified as private, then that member can only be accessed by other members of its class. Now you can understand why main() has always been preceded by the public specifier. It is called by code that is outside the program----that is, by the Java run-time system. When no access specifier is used, then by default the member of a class is public within its own package, but can't be accessed outside of its package.
Usually, you will want to restrict access to the data members of a class----allowing access only through methods. Although methods will usually provide access to the data defined by a class, this does not always have to be the case. It is perfectly proper to allow an instance variable to be public when there is good reason to do so.