Lecture 13
Java packages
In Java, a package is a collection of classes and Java interfaces, and possibly subpackages, that trust each other.
Packages have three benefits.
- Packages can contain hidden classes that are used by the package but are not visible or accessible outside the package.
- Classes in package can have fields and methods that are visible by all classes inside the package, but not outside.
- Different packages can have classes with the same name. For example,
java.awt.Frame
andphoto.Frame
.
Package names are hierarchical.
Using Packages
Address any class, field, or method with a fully-qualified name.
java.lang.System.out.println("My fingers are tired.");
Use import
.
import java.io.File; // Can now refer to File class, not just java.io.File.
import java.io.*; // Can now refer to everything in java.io.
Java implicitly imports java.lang.*
.
Same name: should qualify their name explicitly.
Where are these packages?
Any package you create must appear in a directory of the same name. For example, the photo.Frame class bytecode appears in photo/Frame.class, and x.y.z.Class appears in x/y/z/Class.class. Where are the photo and x directories? They can appear in any of the directories on your "classpath". You can specify a classpath on the command line, as when you type
javac -cp ".:~jrs/classes:libraries.jar" *.java
This means that Java first looks in ".", the current directory, then looks in ~jrs/classes/, then finally in the Java_archive libraries.jar when it's looking for the photo and x directories. The classpath does not include the location of the Java standard library packages (those beginning with java or javax). The Java compiler knows where to find them.
Building Packages
Annonated with package
command - specify the name (should match the dir in which the file appear).
/* list/SList.java */ | /* list/SListNode.java */
|
package list; | package list;
|
public class SList { | class SListNode {
SListNode head; | Object item;
int size; | SListNode next;
} | }
package protection
- falls somewhere between
private
andprotected
- variables are package by default
- only visible to any class in the same package
Visible: in the same package in a subclass everywhere
Declaration
"public" X X X
"protected" X X
default (package) X
"private"
Before we knew about packages, we had to make the fields of SListNode public so that SList could manipulate them. Our list package above solves this problem by giving SListNode and its fields package protection, so that the SList class may use SListNodes freely, but outside applications cannot access them.
In Homework 4, you'll see a different approach. There, the DListNode class is public, so that DListNodes can be directly held by application programs, but the "prev" and "next" fields have package protection, so an application cannot access these fields or corrupt the DList ADT. But an application can hop quickly from node to node because it can store DListNode references and use them as parameters in DList method calls.
A class with package protection can be declared in any .java file.
Compile and run.
javac -g list/SList.java
java list.SList
Iterators
In java.util there is a standard Java interface for iterating over sequences of objects.
public interface Iterator {
boolean hasNext();
Object next();
void remove; // optional
}
next()
throws an exception if there is no more - checkhasNext()
every time or catch exceptions.- can have many interators independently working
- cannot reset it to the beginning of the sequence
Most data structures that support Iterators "implement" another interface in java.util called "Iterable".
public interface Iterable {
Iterator iterator();
}
Benefit: use Java built-in loop syntax.
for (Object o : l) {
System.out.println(o);
}
This loop is equivalent to
for (Iterator i = l.iterator(); i.hasNext(); ) {
Object o = i.next();
System.out.println(o);
}
Example: implementation of SListIterator
and a partial implementation of SList
, both in the "list" package.
/* list/SListIterator.java */
package list;
import java.util.*;
public class SListIterator implements Iterator {
SListNode n;
public SListIterator(SList l) {
n = l.head;
}
public boolean hasNext() {
return n != null;
}
public Object next() {
if (n == null) {
/* We'll learn about throwing exceptions in the next lecture. */
throw new NoSuchElementException(); // In java.util
}
Object i = n.item;
n = n.next;
return i;
}
public void remove() {
/* Doing it the lazy way. Remove this, motherf! */
throw new UnsupportedOperationException("Nice try, bozo."); // In java.lang
}
}
/* list/SList.java */
package list;
import java.util.*;
public class SList implements Iterable {
SListNode head;
int size;
public Iterator iterator() {
return new SListIterator(this);
}
[other methods here]
}
Observe that an Iterator may mess up or even crash the program if the structure it is iterating over changes. For example, if the node "n" that an SListIterator references is removed from the list, the SListIterator will not be able to find the rest of the nodes.
An Iterator doesn't have to iterate over a data structure. For example, you can implement an Iterator subclass called Primes that returns each successive prime number as an Integer object.