CMSC 331
Spring 1999
• Present the syntax of Java
• Introduce the Java API
• Demonstrate how to build
– stand-alone Java programs
– Java applets, which run within browsers e.g.
Netscape
• Example programs tested using Java on
Windows 98 and/or SGI
• Object-oriented programming language
– clean, simple syntax
– similar to C, but without complexity of C++
• Comprehensive API (application program interface)
– platform independence
– useful classes and methods
• Prepare the file foo.java
using an editor
• Invoke the compiler: javac foo.java
• This creates foo.class
• Run the java interpreter: java foo
• The .class files generated by the compiler are not executable binaries
– so Java combines compilation and interpretation
• Instead, they contain “byte-codes” to be executed by the Java Virtual Machine
– other languages have done this, e.g. UCSD Pascal
• This approach provides platform independence, and greater security
public class HelloWorld { public static void main(String[] args) {
System.out.println("Hello World!");
}
}
• Note that String is built in
• println is a member function for the
System.out class
• The JAVA virutal machine may be executed under the auspices of some other program, e.g. a Web browser.
• Bytecodes can be loaded off the Web, and then executed locally.
• There are classes in Java to support this
• Prepare the file foo.java
, and compile it to create foo.class
• Invoke an Applet Viewer, or a Java-aware browser such as Netscape, and open an
HTML file such as foo.html
• Browser invokes the Java Virtual Machine
import java.applet.*; public class HelloWorld extends Applet { public void init() {
System.out.println("Hello, world!");
}
}
<title>Hello, World</title>
<h1>Hello, World</h1>
<applet code="HelloWorld.class" width=100 height=140>
</applet>
• Primitive data types similar to C
– boolean true and false
– char 16 bits UNICODE
– byte, short, int, long integers; 8, 16, 32 and 64 bits respectively
– float and double IEEE 754
• Declared in two ways:
– float Vector1[] = new float[500];
– int Vector2[] = {10, 20, 30, 40};
• Not allocated on stack, but dynamically
• Are subject to garbage collection when no more references remain
– so fewer memory leaks
– Java doesn’t have pointers!
• Subscripts start at 0 as in C
• Subscript checking is done automatically
• Certain operations are defined on arrays of objects, as for other classes
– e.g. Vector1.length == 500
C:\UMBC\331\java>type echo.java
// This is the Echo example from the Sun tutorial class echo { public static void main(String args[]) { for (int i=0; i < args.length; i++) {
System.out.println( args[i] );
}
}
}
C:\UMBC\331\java>javac echo.java
C:\UMBC\331\java>java echo this is pretty silly this is pretty silly
C:\UMBC\331\java>
• The class is the fundamental concept in
JAVA (and other OOPLs)
• A class describes some data object(s), and the operations (or methods) that can be applied to those objects
• Every object and method in Java belongs to a class
• No global variables
– class variables and methods may be applied to any instance of an object
– methods may have local (private?) variables
• No pointers
– but complex data objects are “referenced”
• Other parts of Java are borrowed from PL/I,
Modula, and other languages
• To show how simple data structures are built without pointers, we’ll build a doublylinked list
– ListItem class has some user data
– first refers to that ListItem object at the front of the queue
– last refers to the object at the end of the queue, i.e. most recently added
public class ListItem { // In file ListItem.java
public Object x; // N.B. a heterogeneous queue public ListItem previous; public ListItem next;
// Constructor operation takes initial value public ListItem(String val) {
// this refers to “current” object this.x = val; this.previous = this.next = null;
} public boolean equals(ListItem c) {
// two ListItems are equal if their string values
// are equal and they point to the same objects return ( x.equals(c.x) && (previous == c.previous) &&
(next == c.next) );
}
} public void printItem() {
System.out.println(x);
}
import java.applet.*; // overview of fifo.java
public class fifo extends Applet { private int count = 0; public ListItem first = null; // first is the next item to be removed public ListItem last = null; // last is the item most recently added
// Called to initialize and test the applet. More detail on next page.
public void init() {
System.out.println("isEmpty returns "+isEmpty()); putQueue("node 1");
...
getQueue().printItem();
...
}
// See if the queue is empty public boolean isEmpty() { ... }
// Add an item to the queue public void putQueue(String value) { ... }
}
// Get the first item off the front of the queue public ListItem getQueue() { ... }
// Called to initialize and test the applet.
public void init() {
System.out.println("isEmpty returns "+isEmpty()); putQueue("node 1");
System.out.println("First node is "); first.printItem();
System.out.println("Last node is "); last.printItem(); putQueue("node 2");
System.out.println("First node is "); first.printItem();
System.out.println("Last node is "); last.printItem(); getQueue().printItem();
System.out.println("First node is "); first.printItem();
System.out.println("Last node is "); last.printItem(); getQueue().printItem();
System.out.println("isEmpty returns "+isEmpty());
}
// See if the queue is empty public boolean isEmpty() { return (count == 0);
}
// Add an item to the queue public void putQueue(String value) {
ListItem newItem = new ListItem(value);
} if ( isEmpty() ) { // Special case of empty queue first = last = newItem;
} else {
// next is the next item in the queue
// previous is the item (if any) that was in the
// queue right ahead of this (current) item last.next = newItem; newItem.previous = last; last = newItem;
} count++;
// Get the first item off the front of the queue public ListItem getQueue() {
ListItem firstItem = first;
// Make sure the queue isn't empty if (isEmpty() ) {
System.out.println("Called getQueue on an empty queue");
} else { this.first = firstItem.next;
// Did we just remove the only item in the queue?
if (first == null) { last = null;
} else { first.previous = null;
} count--;
} return firstItem;
}
• Note that the integer variable count , and first and last (both of type ListItem , are redundant in that
– first and last are null iff count == 0
– first == last , but both not null iff count == 1
– otherwise first != last iff count > 1
• Java has no assert macro, but we can test and throw an exception.
// See if the queue is empty
// Check consistency of count, first and last
// Note that exceptions are first-class objects class CorruptFifoException extends Exception;
...
public boolean isEmpty() { if (count == 0) { if (first == null && last == null) { return (true);
} else { throw new
CorruptFifoException(“first and last should be null”);
}
} else { // count != 0
...
}
}
• Lots of similarity to C++
– expressions (, operator okay only in loops)
– control structures same, except breaks and continues may have labels, e.g. to escape from switch statements
– Java has single inheritance
– Java doesn’t do templates
• A class may extend only one class, but it may implement many others
• A subclass inherits the variables and methods of its superclass(es), but may override them
• Overrides the methods defined in the class(es) it implements, as in upcoming thread example
• Classes may be grouped into packages
• Six packages come with Java
• Packages add functionality without extending the language per se
• The import statement lets you use a method without its package name, e.g. import java.applet.* provides Applet class
• The methods of an abstract class are implemented elsewhere
• A final class cannot be extended
• Instances of a synchronizable class can be arguments of a synchronize block
– Which means that access to “critical sections” is restricted
• Methods in a public class can be used outside. The file foo.java
must contain exactly one public class: public class foo
• Methods in a private class can be used only within a file
• Default: class is accessible within current class package
• Applets have many restrictions, which can be relaxed!
– no system calls
– limited network access after local file system is touched
– many others
• Exceptions are objects in their own right
• They can be generated, caught and handled under program control
• Examples: IOException,
ArithmeticException, etc.
• Associates a set of statements with one or more exceptions and some handling code try {
Thread.sleep(200);
} catch(InterruptedException e){
System.out.println(e);
} finally {
System.out.println(“Wakeup”);
}
• An API User’s Guide, in HTML, is bundled with Java
• Much of the “learning curve” is in the API
• Let’s look at some packages
• java.applet
– Applet class
• java.awt
– Windows, buttons, mouse, etc.
• java.awt.image
– image processing
• java.awt.peer
– GUI toolkit
• java.io
– System.out.print
• java.lang
– length method for arrays; exceptions
• java.net
– sockets
• java.util
– System.getProperty
• The class Object
– The root class in Java
– Example methods: clone(), equals(), toString()
– Subclasses may override these methods
• The class Class
– Example methods: getName(), getSuperClass()
void printClassName (Object obj) {
System.out.println("The class of " + obj +
" is " + obj.getClass().getName());
}
• Many methods defined in class java.lang:
– Several constructors
– concat(), equals(), indexOf(), length()
– Strings are immutable (why?)
– strings are concatenated with +
• Several methods defined in class java.lang:
– Constructors can specify length or initial value
– append(), insertf(), length(), toString()
• Printstreams
– System.out.err(“Error message”);
• Inputstreams
– System.in.read(inputCharacter)
– System.in.read(inputBuffer, 0, maxChars)
• A class implements the cloneable interface by overriding the Object method clone()
• For example, we could add a clone() method to the FIFO class, if we wanted to be able to make copies of queues.
• Interface to host OS
• Some basic functions and data structures
– BitSet, Dictionary (the superclass of
Hashtable), Stack, Vector
– Random number generation
• System properties are like UNIX environment variables, but platform independent
• The API class java.util
has methods for accessing the system properties
// determine environment variables import java.util.*; class envSnoop { public static void main ( String args[] ) {
Properties p;
String s; p = System.getProperties(); p.list(System.out); s = System.getProperty("user.name");
System.out.println("user.name="+s); s = System.getProperty("user.home");
System.out.println("user.home="+s);
}
}
• The awt class allows you to create
– frames
– buttons
– menus and menubars
– checkboxes
– text areas
– scrolling lists
• “Hello World”, revisited
• The Scribble example
• Both examples adapted from Flanagan’s
“Java in a Nutshell”, first edition
import java.applet.*; import java.awt.*; public class SecondApplet extends Applet { static final String message = "Hello World"; private Font font;
// One-time initialization for the applet public void init() { font = new Font("Helvetica", Font.BOLD, 48);
}
// Draw the applet whenever necessary.
// Do some fancy graphics.
public void paint(Graphics g) {
// The pink oval g.setColor(Color.pink); g.fillOval(10, 10, 330, 100);
// The red outline. java doesn't support wide lines, so we
// try to simulate a 4-pixel wide line by drawing four ovals g.setColor(Color.red); g.drawOval(10,10, 330, 100); g.drawOval(9, 9, 332, 102); g.drawOval(8, 8, 334, 104); g.drawOval(7, 7, 336, 106);
// The text g.setColor(Color.black); g.setFont(font); g.drawString(message, 40, 75);
}
}
• Graphics objects can be added to applets, e.g. buttons and menus
• Events, such as mouse clicks, are handled
import java.applet.*; import java.awt.*; public class Scribble extends Applet { private int last_x = 0; private int last_y = 0; private Color current_color = Color.black; private Button clear_button; private Choice color_choices;
// Called to initialize the applet.
public void init() {
// Set the background color this.setBackground(Color.white);
// Create a button and add it to the applet.
// Also, set the button's colors clear_button = new Button("Clear"); clear_button.setForeground(Color.black); clear_button.setBackground(Color.lightGray); this.add(clear_button);
}
// Create a menu of colors and add it to the applet.
// Also set the menu's colors and add a label.
color_choices = new Choice(); color_choices.addItem("black"); color_choices.addItem("red"); color_choices.addItem("yellow"); color_choices.setForeground(Color.black); color_choices.setBackground(Color.lightGray); this.add(new Label("Color:")); this.add(color_choices);
// Called when the user clicks the mouse to start a scribble public boolean mouseDown(Event e, int x, int y) { last_x = x; last_y = y; return true;
}
// Called when the user scribbles with the mouse button down public boolean mouseDrag(Event e, int x, int y) {
Graphics g = this.getGraphics(); g.setColor(current_color); g.drawLine(last_x, last_y, x, y); last_x = x; last_y = y; return true;
}
// Called when the user clicks the button or chooses a color public boolean action(Event event, Object arg) {
// If the Clear button was clicked, handle it if (event.target == clear_button) {
Graphics g = this.getGraphics();
Rectangle r = this.bounds(); g.setColor(this.getBackground()); g.fillRect(r.x, r.y, r.width, r.height); return true;
}
// Otherwise if a color was chosen, handle that if (event.target == color_choices) { if (arg.equals("black")) current_color=Color.black; else if (arg.equals("red")) current_color=Color.red; else if (arg.equals("yellow")) current_color=Color.yellow; return true;
}
}
}
// Otherwise let the superclass handle the event else return super.action(event, arg);
• Defines several useful objects:
– URLs
– Internet Addresses
– Sockets
– Datagrams
• packets
• sockets
• A Web server can provide lots of information about a file being sent back in response to an HTTP request.
• A URL can be read
– into a string, using the getContent()
– or opened as a DataInputStream, and read using readLine()
import java.net.*; import java.io.*; import java.util.*; public class GetURLInfo {
// Create a URL from the specified address, open a connection
// to it, and then display information about the URL.
public static void main(String[] args) throws MalformedURLException, IOException {
URL url = new URL(args[0]);
URLConnection connection = url.openConnection(); printinfo(connection);
}
public static void printinfo(URLConnection u) throws IOException {
// Display the URL address, and information about it.
System.out.println(u.getURL().toExternalForm() + ":");
System.out.println(" Content Type: " + u.getContentType());
System.out.println(" Content Length: " + u.getContentLength());
System.out.println(" Last Modified: " + new Date(u.getLastModified()));
System.out.println(" Expiration: " + u.getExpiration());
System.out.println(" Content Encoding: " + u.getContentEncoding());
}
}
// Read and print out the first five lines of the URL.
System.out.println("First five lines:");
DataInputStream in = new DataInputStream(u.getInputStream()); for(int i = 0; i < 5; i++) {
String line = in.readLine(); if (line == null) break;
System.out.println(" " + line);
}
• UDP - Unreliable datagram packet
• Examples from Flanagan
– Send a UDP packet
– Receive a UDP packet
// This example is from the book _Java in a Nutshell_ by
// David Flanagan.
// Written by David Flanagan.
// Copyright (c) 1996 O'Reilly & Associates.
// You may study, use, modify, and distribute this example for
// any purpose. This example is provided WITHOUT WARRANTY
// either expressed or implied.
import java.io.*; import java.net.*;
// This class sends the specified text as a datagram to
// port 6010 of the specified host.
public class UDPSend { static final int port = 6010; public static void main(String args[]) throws Exception { if (args.length != 2) {
System.out.println(
"Usage: java UDPSend <hostname> <message>");
System.exit(0);
}
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName(args[0]);
// Convert the message to an array of bytes int msglen = args[1].length(); byte[] message = new byte[msglen]; args[1].getBytes(0, msglen, message, 0);
}
// Initilize the packet with data and address
DatagramPacket packet = new DatagramPacket(message, msglen, address, port);
// Create a socket, and send the packet through it.
DatagramSocket socket = new DatagramSocket(); socket.send(packet);
}
import java.io.*; import java.net.*;
// This program waits to receive datagrams sent to port 6010.
// When it receives one, it displays the sending host and port,
// and prints the contents of the datagram as a string.
public class UDPReceive { static final int port = 6010; public static void main(String args[]) throws Exception
{ byte[] buffer = new byte[1024];
String s;
// Create a packet with an empty buffer to receive data
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Create a socket to listen on the port.
DatagramSocket socket = new DatagramSocket(port);
for(;;) {
// Wait to receive a datagram socket.receive(packet);
// Convert the contents to a string s = new String(buffer, 0, 0, packet.getLength());
// And display them
System.out.println("UDPReceive: received from " + packet.getAddress().getHostName() +
":" + packet.getPort() + ": " + s);
} // close for
} // close main
} // close class UDPReceive
• Thread objects are the basis for multithreaded programming.
• Multi-threaded programming allows a single program to conduct concurrently running threads that perform different tasks.
• Defined in java.lang.Thread
• A class that implements this interface can provide the “body” of a thread
• The run() method needs to be specified
• The simpleThread class implements the
Runnable interface
– Implements run() method for Runnable interface
– Implements init(), start() and stop(), extending Applet class
– Can’t just extend Thread class, since
Thread.stop() is final and can’t be overriden (why?)
// Simple Thread Example, based on "Neon Sign" public class OneThread extends java.applet.Applet implements Runnable {
Thread kicker; public void init() { kicker = null; } public void start() { if(kicker == null) { // If no thread is started yet kicker=new Thread(this); // then create one kicker.start(); // and start it
}
} public void stop() { kicker.stop(); kicker = null; }
public void run() { long sleepTime;
System.out.println("Hello!"); sleepTime = 5000;
}
} while(true) { // Loop forever
// The sleep method below might be interrupted
// and cause an exception, so catch it.
try {
// Wait for some period of time
Thread.sleep( sleepTime ); sleepTime = (sleepTime == 3000 ? 4000 : 3000 );
} catch (Exception e){ return; }
System.out.println("Hello again after "+sleepTime+
" milliseconds");
}
• Start a thread
• Load two GIF images
• Repeat forever
– Display first image
– Sleep a random period of time
– Display the other image
// Blinking Neon Light by Mattias Flodin import java.awt.*; public class BlinkItem extends java.applet.Applet implements Runnable {
Image imPic[]; // Array that holds the two images int iPicIndex=0; // Keeps track of which image is displayed
Thread kicker; public void init() {
// *Always* resize, in case the HTML author forgot to
// include WIDTH and HEIGHT tags resize(512,243);
} public void Paint(Graphics g) { update(g); }
// Using the update method will get rid of some flickering public void update(Graphics g) {
// Display an error message if something
// unexpected has happened to the images if(imPic[iPicIndex]==null) g.drawString("Error when loading picture", 0, 172);
}
// Draw the current image g.drawImage(imPic[iPicIndex],0,0, this);
public void start() { if(kicker == null) { // If no thread is started yet kicker=new Thread(this); // then create one kicker.start(); // and start it
}
} public void stop() { kicker=null; } public void run() { imPic=new Image[2]; // Dimension the image array
// Load the two images in our 'animation' imPic[0]=getImage(getCodeBase(), "images/Homepage1.gif"); imPic[1]=getImage(getCodeBase(), "images/Homepage2.gif");
}
} for(;;) { // Loop forever repaint(); // Redraw the window iPicIndex=iPicIndex==0 ? 1 : 0; // Switch image
// The sleep method below might be interrupted
// and cause an InterruptedException, so we'll
// have to catch it.
try {
// Wait for a random amount of time
Thread.sleep( (int) (Math.random()*500));
} catch (InterruptedException e){}
}
• An applet that creates a pool of simple threads
• Each thread has an ID number, and may handle different tasks
• Note separation of applet and thread classes
public class ThreadExample extends java.applet.Applet {
} public void init() { simpleThread[] threadPool = new simpleThread[2]; threadPool[0] = new simpleThread(1); threadPool[1] = new simpleThread(2);
}
public class simpleThread implements Runnable {
Thread thisThread; int thisThreadID; public simpleThread (int i) { thisThreadID = i; this.start(); } public void start() { if(thisThread == null) { // If thread isn’t started thisThread = new Thread(this); // create one thisThread.start(); // and start it
}
} public void stop() { thisThread.stop(); thisThread = null; }
public void run() { long sleepTime;
System.out.println("Hello from simpleThread "+ thisThreadID); while(true) {
// The sleep method below might be interrupted
// and cause an exception, so catch it.
try {
// Wait for a random amount of time sleepTime = (long) ( Math.random()*4 );
Thread.sleep( sleepTime*1000 );
} catch (Exception e) { return;
}
System.out.println("Hello again from simpleThread "+ thisThreadID+" after "+sleepTime+" seconds");
}
}
}
• Patterns as an addition to the StringBuffer class (ala Perl)
• One could easily write a better browser
– intelligent pre-fetching of URLs
– other ideas?
• There are now many decent Java books, e.g.
Dietel and Dietel, and the second edition of
Flanagan
• Many other web resources