It is possible, though not typical, to have a compilation unit with no
public class at all. In this case, you can name the file whatever you
like.
When you create a package-access class, it still makes sense to make the fields of the class privateyou should always make fields as private as possiblebut its generally reasonable to give the methods the same access as the class (package access). Since a package-access class is usually used only within the package, you only need to make the methods of such a class public if youre forced to, and in those cases, the compiler will tell you.
Note that a class cannot be private (that would make it accessible to no one but the class) or protected.[30] So you have only two choices for class access: package access or public. If you dont want anyone else to have access to that class, you can make all the constructors private, thereby preventing anyone but you, inside a static member of the class, from creating an object of that class. Heres an example:
//: c05:Lunch.java
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:
class Soup {
private Soup() {}
// (1) Allow creation via static method:
public static Soup makeSoup() {
return new Soup();
}
// (2) Create a static object and return a reference
// upon request.(The "Singleton" pattern):
private static Soup ps1 = new Soup();
public static Soup access() {
return ps1;
}
public void f() {}
}
class Sandwich { // Uses Lunch
void f() { new Lunch(); }
}
// Only one public class allowed per file:
public class Lunch {
void test() {
// Can't do this! Private constructor:
//! Soup priv1 = new Soup();
Soup priv2 = Soup.makeSoup();
Sandwich f1 = new Sandwich();
Soup.access().f();
}
} ///:~
Up to now, most of the methods have been returning either void or a primitive type, so the definition:
public static Soup access() {
return ps1;
}
might look a little confusing at first. The word before the method name (access) tells what the method returns. So far, this has most often been void, which means it returns nothing. But you can also return a reference to an object, which is what happens here. This method returns a reference to an object of class Soup.
The class Soup shows how to prevent direct creation of a class by making all the constructors private. Remember that if you dont explicitly create at least one constructor, the default constructor (a constructor with no arguments) will be created for you. By writing the default constructor, it wont be created automatically. By making it private, no one can create an object of that class. But now how does anyone use this class? The preceding example shows two options. First, a static method is created that creates a new Soup and returns a reference to it. This could be useful if you want to do some extra operations on the Soup before returning it, or if you want to keep count of how many Soup objects to create (perhaps to restrict their population).
The second option uses whats called a design pattern, which is covered in Thinking in Patterns (with Java) at www.BruceEckel.com. This particular pattern is called a singleton because it allows only a single object to ever be created. The object of class Soup is created as a static private member of Soup, so theres one and only one, and you cant get at it except through the public method access( ).
As previously mentioned, if you dont put an access specifier for class access, it defaults to package access. This means that an object of that class can be created by any other class in the package, but not outside the package. (Remember, all the files within the same directory that dont have explicit package declarations are implicitly part of the default package for that directory.) However, if a static member of that class is public, the client programmer can still access that static member even though they cannot create an object of that class.