- When writing a java source code file, this file is often referred to as a compilation unit. Each compilation unit must have a suffix. Java, and there is a public class in the compilation unit. The name of this class must be the same as the name of the file.
- A Java runnable program is a set of. class files that can be packaged and compressed into a Java document file (jar, using Java's jar document generator). The Java interpreter is responsible for finding, loading, and interpreting these files.
- The naming rules for Java packages are all lowercase letters.
- Since the constructor is the only defined constructor and it is private, it will prevent inheritance of this class.
package thinkinjava.charpenter6; /** * @author Spring-_-Bear * @version 2021/9/24 16:24 */ public class IceCream { public static void main(String[] args) { // ! Sundae x = new Sundae(); Sundae x = Sundae.makeASundae(); } } class Sundae{ private Sundae(){ System.out.println("Sundae();"); } static Sundae makeASundae(){ return new Sundae(); } }
- Although it is not very commonly used, it is possible to compile a unit without a public class at all. In this case, you can name the file at will.
- A class can neither be private (which will make it inaccessible to any other class outside the class) nor protected. Therefore, there are only two choices for class access: package access or public. If you don't want anyone else to have access to this class, you can specify all constructors as private, so as to prevent anyone from creating objects of this class. One exception is that you can create objects inside the static member of this class. Note: an inner class can be private or protected, but that is a special case.
package thinkinjava.charpenter6; /** * @author Spring-_-Bear * @version 2021/9/24 16:42 */ public class Lunch { public static void main(String[] args) { Soup1.makeSoup(); Soup2.access(); } } class Soup1 { /* Allow creation via static method */ private Soup1() { System.out.println("Soup1();"); } public static Soup1 makeSoup() { return new Soup1(); } } class Soup2 { /* Allow creation via a static object and return a reference */ private Soup2() { System.out.println("Soup2();"); } private static Soup2 ps1 = new Soup2(); public static Soup2 access() { return ps1; } }
The above example gives two options: in Soup1, create a static method, which creates a new Soup1 object and returns a reference to it. If you want to do some extra work on Soup1 before returning the reference, or if you want to record how many Soup1 objects are created (you may want to limit their number); The object of Soup2 class is created as a static private member of Soup2, so there is only one and it can only be accessed through the access() method.
Exercise 1: create a class in a package and an instance of the class outside the package in which the class is located.
/* In another directory: * /access/mypackage/MyPackagedClass.java * The most important thing is to add environment variables to the operating system. * package access.mypackage; * * public class MyPackagedClass { * public MyPackagedClass() {System.out.println("MyPackagedClass()");} * } */ public class UnpackagedMyClass { public static void main(String[] args) { access.mypackage.MyPackagedClass m = new access.mypackage.MyPackagedClass(); } }
Exercise 2: rewrite the code snippets in this section into a complete program and verify the actual conflicts.
import net.mindview.simple.*; import java.util.*; public class Collision { public static void main(String[] args) { // Vector v = new Vector(); // ambiquous collision net.mindview.simple.Vector v1 = new net.mindview.simple.Vector(); java.util.Vector v2 = new java.util.Vector(); } }
Exercise 3: create two packages: debug and debugoff, both of which contain the same class with a debug() method. The first version shows the String parameters sent to the console, while the second version does nothing. Use the static import statement to import this class into a test program and demonstrate the effect of conditional compilation.
/* In directory access/debugoff: * // access/debugoff/Debug.java * package access.debugoff; * * public class Debug { * public static void debug(String s) { } * } */ package access.debug; public class Debug { public static void debug(String s) { System.out.println(s); } }
Exercise 4: show that the protected method has package access, but it is still not public.
package access.cookie2; public class CookieMonster { public static void main(String[] args) { Cookie x = new Cookie(); x.bite(); // package access to protected method } }
import access.cookie2.*; public class CookieThief { public static void main(String[] args) { Cookie x = new Cookie(); //! x.bite(); // access protected } }
Exercise 5: create a class with public, private, protected and package access fields and method members. Create an object of this class and see what type of compilation information you will get when you try to call all class members. Note that all classes in the same directory are part of the default package.
/* in same directory: * package access; * * public class FourWays { * int a = 0; * public int b = 1; * protected int c = 2; * private int d = 3; * FourWays() { System.out.println("FourWays() constructor"); } * void showa() { System.out.println(a); } * public void showb() { System.out.println(b); } * protected void showc() { System.out.println(c); } * private void showd() { System.out.println(d); } * } */ package access; public class AccessTest { public static void main(String[] args) { FourWays fw = new FourWays(); fw.showa(); fw.showb(); fw.showc(); fw.a = 10; fw.b = 20; fw.c = 30; fw.showa(); fw.showb(); fw.showc(); //! fw.showd(); // private access, compiler can't touch } }
Exercise 6: create a class with protected data. Use the method of processing protected data in the first class to create a second class in the same file.
class SomeData { protected int a = 13; } class DataChanger { static void change(SomeData sd, int i) { sd.a = i; } } public class ProtectedData { public static void main(String[] args) { SomeData x = new SomeData(); System.out.println(x.a); DataChanger.change(x, 99); System.out.println(x.a); } }
Exercise 7: create a class library from the code snippets that describe access and widgets. Create a Widget instance in a class that does not belong to the access class library.
/* in access package: * // access/Widget.java * package access; * * public class Widget { * public Widget() { System.out.println("Widget()"); } * } */ import access.*; public class MakeWidget { public static void main(String[] args) { Widget w = new Widget(); } }
Exercise 8: follow the example of Lunch.java and create a class named ConnectionManager, which manages a fixed array whose element is a Connection object. The client programmer cannot directly create Connection objects, but can only obtain them through a static method in the ConnectionManager. When there is no more object in connectionmanage, it returns a null reference. Detect these classes in main().
package thinkinjava.charpenter6; import java.util.Random; /** * @author Spring-_-Bear * @version 2021/9/25 17:25 */ public class ConnectionManager { static int leftObject = 5; static Connection[] connections = new Connection[leftObject]; /* Initial the object's reference */ static { for (Connection c : connections) { c = Connection.makeConnection(); } } /* If the number of objects is greater than zero, return its reference, * otherwise return null */ public Connection getConnection() { if (leftObject > 0) { return connections[--leftObject]; } else { System.out.println("NO MORE CONNECTIONS!"); return null; } } public static void main(String[] args) { ConnectionManager connectionManager = new ConnectionManager(); Random random = new Random(47); int randomNum = random.nextInt(10); for (int i = 0; i < randomNum; i++) { System.out.println("The number of left objects: " + leftObject); connectionManager.getConnection(); } } } class Connection { static int cnt = 0; /* avoid directly creating the object of Connection */ private Connection() { cnt++; System.out.println("Connection(): " + cnt); } /* create a method to create the object of Connection * and return the reference of the object */ static Connection makeConnection() { return new Connection(); } }
Exercise 9: write the following price in the access/local directory (assuming access/local is in your CLASSPATH):
package access.local; class PackagedClass{ public PackagedClass(){ System.out.println("Creating a packaged class.") } }
Then create the following files in a directory other than access/local:
package access.foreign; import access.local.*; public class Foreign{ public static void main(String[] args){ PackagedClass pc = new PackagedClass(); } }
Explain why the compiler generates errors. If you put Foreign in the access.local package, will it change?
/* Compiler Error Reason: PackagedClass in not public, so no access outside of package. Moving Foreign to local would allow package access to PackagedClass.
*/