Docstoc

package

Document Sample
package Powered By Docstoc
					                                   java.notes
                                  Nax Mendler

         Packages: Using existing ones, building your own


1 Using packages.
Packages group together classes and interfaces. In the Java SDK, every class
and interface is in some package, and the on-line documentation indicates where
each one is defined. For example, ArrayList is in package java.util.To use the
classes and interfaces in package java.util, place the following line in your.java
file, before any class definition:

       import java.util.*;

Each file mentioning java.util classes or interfaces will need this line.

What does this statement do? It tells the compiler and the runtime environment
where to search for classes used in your code. It's common to have a half dozen
or a dozen import statements (or more) at the beginning of a .java file. Then you
can simply mention classes and interfaces defined in those packages, like
ArrayList and Iterator, in your code. Without the import line, you would have to
use fully qualified names:

       public void m(java.util.Iterator i) {...}
       private java.util.ArrayList m_list;

You can also choose to import individual classes and interfaces:

       import java.util.ArrayList;
       import java.util.Iterator;

This documents your exact dependency on the package java.util, and that is why
this style is often used in articles and example programs, but it is no more
efficient that using the wild card java.util.* Advice: if you use more that a few
classes from a package, use the wildcard; otherwise maintaining the correct
import statements becomes an exercise in bookkeeping. The order you list
import statements is immaterial. I find listing them alphabetically a simple,
consistent convention. (C /C++ programmers should note that import statements
are very different from the preprocessor directives #include; they are more like
namespace using declarations or directives.)




                                          1
What if there is a name clash? This happens, for example, if you import:

       import java.util.*;
       import java.awt.*;

…and then you go on to mention List. In that case, the easiest thing to further
specifically import the desired one (or use a fully qualified name):

       import java.util.*;
       import java.awt.*;
       import java.util.List;

The SDK packages are nested packages, many with the prefixes java or javax.
There are also some with further nesting, like javax.swing.text.html.parser!
Importing is not "recursive":

       import javax.swing.*;

imports all the classes and interfaces in the swing package but it does not import
those in the package javax.swing.event; for that, you would have to also write:

       import javax.swing.event.*;

One package that you never have to explicitly import is the core language
package, because it is automatically, implicitly imported:

       import java.lang.*;         //don't bother doing this


2 Aside: dots, dots, dots.
Dots, is there anything they can't do? Here is a review of their various uses:

obj.method(args)                   //method application
classX.staticMethod(args)          //static method (scope resolution)
classX.staticObj                   //static object (scope resolution)
packageName.classX                 //fully qualified class name
pack1.nestedpack2.classX           //nested package name

java.lang.System.out.print("crikey!") //for example

In the last example,
     the dot in java.lang punctuates a nested package name;
     the dot in lang.System separates the package name from the class name.
     the dot in System.out is scope resolution for the static object out.
     the dot in out.print is a method applied to an object.




                                         2
3 Defining your own packages
The files of a package must be stored in a folder named after the package, and
the first non-comment line in the file must identify the package:

      package p;

You have to be careful to match case here, even on a Windows platform! The
convention is that package names are all lower case, but class names use
"camel hump" notation, like NoClassDefFoundError. And furthermore, the folder
in which subfolder p is placed must be on the CLASSPATH.

Compiling and running. Unfortunately, TextPad doesn’t understand packages
so you can’t run your Java code from within TextPad by pressing Ctrl+2. (but you
can use Tools | Run…) However, you can still compile with Ctrl+1, then use a
DosPrompt window and execute, for example, class A of package p, by typing:

      java p.A

You can be in any folder when you execute this command! For example, you can
put the previous command in a .bat file on your desktop, where it can be
executed by double-clicking on it.

To use the classes in package p elsewhere, you will use lines like:

import p.*;         //import all classes in p
import p.A;         //for importing one class

Packages represent "modules". Apart from simple test apps, any real
application should organize all its classes into packages. Breaking an application
into packages is something that should be done early in the design process
because it is high-level organization. UML package diagrams are made for this
situation. Recall that one major relation you indicate between packages in this
notation is dependency:

               P                                       Q
                                (depends on)




…when a type in P depends on a type in Q. The aim is to decouple packages as
much as possible – to minimize dependencies. Circular dependencies among
packages are considered especially bad because it implies module-level testing
will be hard to accomplish, and that packages don't reflect layers of abstraction.

                                        3
4 Packages: once you start, you just can't stop.
A class that is in a "module" package cannot use a class that is not in any
package. Suppose our class p.A wants to use B, which is not declared in a
package. Where would you put B.java -- in folder p with A? That won't work at all,
because p.A will assume B is also in package p, so add B to package p:

package p;
import javax.swing.JOptionPane;

public class B
{    public static void main(String[] args)
     {     JOptionPane.showMessageDialog(null, "Hi");
     }
}

package p;

public class A
{    public static void main(String[] args)
     {     B.main(args);
     }
}

Now you can run A from anywhere:

C:> java p.A

And you can use A in a class placed in another folder:

package q; //not in folder p
import p.*;

public class C
{    public static void main(String[] args)
     {     A.main(args);
     }
}

Moral. A class in a package cannot use a class that is not in a package. So if
you start putting an application’s classes into packages, put them all into
packages.




                                        4
5 Finding packages.
The compiler and the runtime environment use import statements to search for
classes – how do they use them? Certainly not by searching your entire hard
drive for folders named p! They may use the environment variable CLASSPATH.
To see its value, go to the DosPrompt and:

C:\>echo %CLASSPATH%
C:\jdk1.3\lib;.;C:\elvis\java\café;

Inside of a program, if you ever (?) need to determine the classpath, call:

String classpath = System.getProperty("java.class.path");

CLASSPATH is a sequence of paths. It should include dot (the current directory)
if you want to run classes that are not placed in packages. These paths identify
the folders where packages are placed. My folder p is in folder café. Again, the
simplest solution is to have at least one folder, here it's "cafe", whose subfolders
are your packages. Edit the environment variable CLASSPATH in your
C:\autoexec.bat file to be like the following:

       SET CLASSPATH=C:\java1.3\LIB;.;C:\elvis\java\cafe;

Then either reboot your machine or execute this file. (Note: be careful about
placing no spaces on either side of that equal sign!)

Note, it is not the package folders you put onto your class path, but their
parent folder(s). The CLASSPATH variable tells Java in which folders to look for
package folders.

5 Minute Exercise. Carry out the A – B -- C example.

Alternative. If you don't want to alter your classpath, you can use command line
arguments. Suppose X.java is the file using package p:

$javac –classpath \elvis\java\cafe;. X.java
$java –classpath \elvis\java\cafe;. X

The "semicolon+dot" allows the tools to find the X files, and other files in the
current directory.




                                          5
6 Nested packages
Nested packages pose no additional difficulties. Suppose folder p has subfolder
sublet. That is where to put classes of package p.sublet. Their files begin with:

package p.sublet;

In the real world, package names are often built starting with "reversed" URLs:

import com.sun.image.codec.jpeg.*;                   //not quite in the SDK
import org.omg.CORBA.*;

Aside: where are the SDK .class files? They should be below \jdk1.x\lib, but
they are actually in \jdk1.x\jre\lib\rt.jar. Jar files act like folders, so
they don't need to be expanded to be used. If you want to see what's in it, type:

       jar tf rt.jar > output.txt

(t is for "table-of-contents" and the f is for "file". Typing jar will list all options.
View output.txt in TextPad. There will be over 5,000 class files!)

Aside: where are the SDK .java files? They're in \jdk1.x\src.zip. You can learn
lots about Java/SDK by reading the source code. If the source code hasn't been
unzipped already, you can use the jar utility to do it for you:

       jar xf src.zip

Libraries (= sets of packages) are distributed as *.jar or *.zip files. But you don't
have extract the files in order to use them. To use a library stored in a *.zip or
*.jar file, you can either include the file on your classpath:

SET CLASSPATH=C:\jdk1.3\LIB;.;C:\elvis\example\zap.jar

Or use the command line argument approach (here I'm assuming the jar file is in
the same directory as X.java)

$javac –classpath zap.jar;. X.java
$java –classpath zap.jar;. X

Note. Updating your autoexec.bat is the best approach. But if you are just
sampling a library, the classpath approach is easier to try.




                                             6
Executable jar files are the easiest way distribute your Java application. To
execute them, just double click! Steps:

    1. Create a manifest file. Manifests are the table of contents in a jar: The
       class you name here has the application’s main. This file can have any
       name, but give it extension .mf – here is its contents: (A fully qualified
       class name is MyApp or p.A etc…)

    Main-Class: fully_qualified_main_class_name

    2. Jar it! The filename order is significant (jar, manifest, the rest)…

    jar cvfm app.jar main.mf *.class *.gif etc…

    3. By the way, double-clicking on the jar is equivalent to executing:

    javaw –jar app.jar

    If you have a runtime error in your application you won't see the stack trace
    because javaw leaves the DOS window invisible. In that case, type:

    java –jar app.jar

Warning. A common mistake triggered when you move an application into a jar
is the use of relative paths for resource files:

Ike = new ImageIcon(“fig.gif"); 
Ike = new ImageIcon(getClass().getResource("fig.gif")); 

In the first version, the loader won’t look in the jar file for the gif file.

5 Minute Exercise. If you have packages p and q, with files:
      …café\q\C.*
      …café\p\A.*
      …café\p\B.*
Do the following command in folder café to create an executable jar
        jar cvfm ex.jar main.mf q\*.class p\*.class
This executable has a bug. Run the jar and then run the Windows Task Manager
and you may see it… What is the bug and what one line of code fixes it?

Answer. Because B displays a JOptionPane, an EventDispatchThread is started. It is not a
daemon thread, so it continues to run after the main user thread terminates. Use the Task Manager
to terminate javaw.exe. To fix this bug, one of the main() methods in the application should finally
call System.exit().




                                                 7
7 The fourth access level: "package"
Public and private access are the most common levels, but there are two others:

   1. protected -- protected members are visible in the class, in derived classes
      and unexpectedly to other classes in the same package.
   2. The default access (pronounced "package" access) -- members with this
      protection are visible to classes in the same package, but not to classes in
      other packages.

To order these access levels from most restrictive to most accessible, it is:

       private, (default), protected, public


      Java versus C++. C++ namespaces approximate packages in Java.


 a fact: when you override a method you may change its access, but
  It's
only to make it more visible: for instance, overriding a protected method with a
public version. (this is often done with clone().) Overriding in the other direction
will be a syntax error.

Access Suggestions:

 Resist the urge to give data protected or "package" access. The wider the
access the harder it is to write good code.




                                          8
An access example.

       P                                      Q

               E               C                  G




               D                                  F



Suppose classes are placed in packages and derived as shown, and C is:

package p;

public class C
{    public                   void   pub()         {}
     protected                void   pro()         {}
     /*package*/              void   pac()         {}
     private                  void   pri()         {}
}

Then this table summarizes who can send which message to C objects

                      C            D              E          F            G
   pub               yes           yes         yes          yes          yes
   pro               yes           yes         yes          yes           no
   pac               yes           yes         yes           no           no
    pri              yes           no             no         no           no

          Being unrelated, the only yes in G's column is for public access.
          Being derived and in a different package, F can access public and
           protected members.
          Being in the same package, E can access public, "package" and protected
           members.
          Being derived and in the same package D has the same access as E.
          C's column is all yeses because a class can't hide from itself.




                                          9
Outermost class access
Here we are discussing the type of classes we've seen so far – top-level classes
(classes not defined inside any class or context.). Class access will be more
generally defined for inner classes.

Outermost classes can have either public or default (package) access:

public               class Pub {}

/*package*/          class Pac {}

Public classes are visible outside the package, while package-access classes
are not. Think of package-access classes as implementation details shared
across the entire package.

1. You are allowed to have at most one public class per file, but as many
   package-access classes as you wish.
2. With a public class, the class name must be the same as the name of the file.

Access Suggestions:

 Keep to one (top-level) public class per file, and don't worry about package-
access classes until you have to consider your package from the vantage point of
another package.

8 Packages in Applets.

If some classes used in an applet are in packages, how will they be found when
you run the applet on a different machine, far from the original CLASSPATH
environment variable?

The simple solution is to jar the necessary class files (and for efficiency reasons,
you should always jar an applet's files anyway) in the same fashion as the 5
minute exercise on page 7. The paths stored in the jar file provide the package
information. Recall that if needed, an applet can have multiple jar archives.

<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
     CODEBASE="http://java.sun.com/products/plugin/1.1.1/jinstal
l-111-win32.cab#Version=1,1,1,0"
     WIDTH = 300 HEIGHT = 300 ALIGN = LEFT>

<PARAM NAME="TYPE" VALUE="application/x-java-applet;version=1.1">
<PARAM NAME="CODE" VALUE="YourApplet.class">
<PARAM NAME="ARCHIVE" VALUE="your.jar">

</OBJECT>




                                         10

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:5
posted:11/3/2011
language:English
pages:10