Chapter 6: Scope of Classes

6.1: Setting Up the Java Environment - PATH & CLASSPATH

The environment variable CLASSPATH is a variable of the operating system. It specifies the directory where Java compiler searches for classes. It can specify multiple directories.

There are two ways to set the CLASSPATH variable: setting it permanently, or temporarily every time before you use.

The order of the entries defined by CLASSPATH is important. When the JVM is looking for a class, it searches the default directories specified by CLASSPATH in order, until it finds a class with the correct name. It loads the first found class and does not search the remaining directories.

The "." directory should be the first parameter in the list - if you want Java to start searching from the current directory.

Because DOS only recognize identifiers of less then eight characters, when you have a path name longer than eight, use "~1" or "~2" to abbreviate it to eight when putting it into CLASSPATH. For example, "c:\My Documents" will be "c:\mydocu~1".

Suppose Java is installed in directory C:\jdk1.2, Swing is in C:\swing, and you also want "c:\000Frank" to be included:

* Setting CLASSPATH Permanently

Add the following lines to your system's AUTOEXEC.BAT file:

   
   set JAVA_HOME=C:\JDK1.3
   set SWING_HOME=C:\swing
   set CLASSPATH=.;%SWING_HOME%\swing.jar;C:\J2EE\lib\j2ee.jar;c:\000Frank
   set PATH=%PATH%;%JAVA_HOME%\bin
   

Double-click the System icon inside the Control Panel. When the System Properties dialog box opens, choose the Environment tab and then place the following in the lower list box, which is labeled "User Variables":

   
   JAVA_HOME    C:\JDK1.2
   SWING_HOME    C:\swing
   CLASSPATH    .; %SWING_HOME%\swing.jar;C:\J2EE\lib\j2ee.jar;c:\000Frank
   PATH    %PATH%;%JAVA_HOME%\bin

* Setting CLASSPATH Temporarily

   
   javac -classpath .:~/classes:/JDK/lib/classes.zip

Listed on Java website, not proved.

On DOS prompt, in any directory, type in or run a batch file

   
   set PATH=C:\JDK1.3\bin;C:\JDK1.3;
   set CLASSPATH=.;C:\J2EE\lib\j2ee.jar;c:\jdk1.3;c:\000Frank;

Remember that when you specify a class path in this manner, you completely override the current class path. If you do not want to override the current one but only want to append to it, you can say

   
   set PATH=%PATH%;C:\JDK1.3
   set CLASSPATH=%CLASSPATH%;C:\JDK1.3

6.2: Package

Packages are used to split the global name space into sub-spheres. Classes in different packages can have the same name. So package plays the role of namespace in C++.

* How to use package

A package represents a sub-directory in the computer's hard disk. The name of the package must be the same as a physical directory. For example, if you invoke a class in a package:

   
   import frank.tools.Test;
   ...
   Test t1 = new Test();

and the default directories specified by system variable CLASSPATH is "c:\mydocu\Java", then there must be a sub-directory named

   
   "c:\mydocu\java\frank\tools"

and class Test must can be found in that directory, and it must acknowledge that it belongs to this package by putting

   
   package frank.tools;

at its beginning.

Attention: all package names, including those in the import, forName or in the package declaration, are case sensitive. The path in the CLASSPATH line is not.

* Making your package unique

When you give your code to someone else to use, it is possible that he has a directory in his computer with the same name as the package specified in your code, and in his directory there is a program with the same name as yours. Then there will be a run-time error.

One way to make your package name unique all around the world is to use your domain name - if you have one. Suppose my domain name is "www . frankliu . com . au", then I can use package name "au .com .frankliu .tools", and the create the following directory in my computer:

   
   "c:\mydocu\java\au\com\frankliu\tools".

if you do not use the import statement, you have to invoke that class like

   
   frankliu .tools .Test t1 = new frankliu .tools .Test();

If you have two libraries and they contain two classes with the same name, then you still have to use the package name in front of the class name as above to avoid confusion.

* Default Package

If a group of files have no package definition and are in one directory, Java will regard them implicitly as members of a default package of that directory. Therefore, they can access each other's friendly members.

However, a class without package name can only be recognized by its package peers. A class in another directory can not access it - even if the CLASSPATH is pointing to that directory. Therefore, if a class needs to be accessed elsewhere, it must have a package name.

6.3: Access Specifiers

The definition of Java's private, protected and public is the same as C++, but Java's "friendly" is different from C++'s "friend".

In C++ a specifier controls all the following members and methods, but in Java each member or method should be specified separately.

* private

Only the class's own members can access it. Package members, clients and derived classes can not. Private methods are by default final, which means that they can not be overridden.

* friendly = private + package member

If you don't put any specifier in front of a member, it is by default friendly. All the classes of the same package can access it. Clients and derived classes can not.

* protected = friendly + derived class

Package members and derived classes can access it. Clients can not.

* public member

All can access it.

To prepare for inheritance, as a guidance line, make all fields private and all methods at least protected, because derived class can not access friendly methods if it doesn't belong to the same package.

6.4: Class Accessibility

A class can only have two kinds of access: public or friendly. Each compilation unit can only have one public class, whose name should be the same as the file. There can be more classes in that file, but they can only be facility classes which support the public class. They are not public and thus not accessible for the clients, but they are accessible for package members.

Classes with no specifiers are by default friendly, which can be accessed by package members but not outside clients. It is not forbidden for a compilation unit to have no public class but only friendly classes, whose names do not have to be the same as the file. But this is not very common.

If a friendly class contains a public member, the member can still be accessed by outside clients, although clients can not create an object of that class.

If you do not want anyone else including package members to use a class, you can make all the constructors private.