1.124 Lecture 10 10/20/1998

Programming in Java

Contents

1. Introduction

Java is an object-oriented programming language that resembles C++ in many respects.  One of the major differences is that Java programs are intended to be architecture-neutral i.e. a Java program should, in theory, be able to run on a Unix workstation, a PC or a Macintosh without recompilation.   In C++, we compiled our programs into machine-dependent object code that was linked to produce an executable.  By contrast, Java programs are compiled into machine-independent byte code.  The compiled program is then run within a Java interpreter, which is responsible for executing the byte code instructions.  The Java interpreter is typically referred to as the Java Virtual Machine, and it must be present on each computer that runs the program.
 
Java compiler Java interpreter
myprog.java --------------> myprog.class ----------------> Program output
javac java 
appletviewer 
netscape
Follow this link to see Sun Microsystems' overview:  http://java.sun.com/docs/books/tutorial/getStarted/intro/definition.html

Learning all that there is to know about Java takes time, and it is important to set your expectations accordingly.  There are two types of battles to be fought

In the lectures that follow, we will attempt to familiarize you with the basic syntax, and point out the syntactic and semantic differences between Java and C++.  We will also introduce you to some of the more important class libraries, such as the java.lang package and the java.awt package.  The Java API is well documented and you should quickly become comfortable navigating the online documentation for the classes that you need.

The Java language is still evolving.  The latest official release of the Java Development Kit (JDK) is version 1.1.7.  The latest unofficial release of the JDK is version 1.2 Beta 4.  We will be using the version that is available on Athena, which is JDK 1.1.6.  Beware of these differences.  Also, note that in practice, Java does vary somewhat from platform to platform.  The platform that we will be officially supporting is the Sun Solaris platform.
 

2. Online Java Resources

Here are some online Java resources.

3. Applications and Applets

An application is a stand-alone program that executes independently of a browser.  It is usually launched from the command line, using the command line interpreter, java.

An applet is a program that can be embedded in an HTML page.  The program can be run by loading the page into a Java-enabled browser.  The JDK includes a tool, called appletviewer, that can also be used to view applets.

A Java program can be designed to function

 

The Hello World Application

Here is an example of a simple Java application.  We make our program an application by writing a class, HelloWorldApp, that contains a function named main().  We can compile our program by typing

    javac HelloWorld.java

This will produce a file named HelloWorldApp.class.

We can run the program as application by typing

   java HelloWorldApp

The command line interpreter looks for a function named main() in the HelloWorldApp class and then executes it.

Points to note:

HelloWorld.java

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
 
 

The Hello World Applet

Here is an example of a simple Java applet.  We make our program an applet by writing a class, HelloWorld, that inherits the Applet class provided in the Java Core API.  The extends keyword declares that class HelloWorld inherits class Applet.  Before we can refer to the Applet class, we must declare its existence using the import keyword.  Here we have imported the Applet class, which belongs to the java.applet package, and we have also imported the Graphics class, which belongs to the java.awt package.

The Applet class possesses a method named paint(), which it inherits from one of its superclasses.  Our HelloWorld class inherits this paint() method when it inherits the Applet class.  The purpose of paint() is to draw the contents of the applet.  Unfortunately, however, the default paint() method that we inherit cannot do anything useful since it has no way of knowing what we want to draw.  We must therefore override the default paint() in our HelloWorld class.  (This behavior is comparable to that of virtual functions in C++.)

The paint() method receives as an argument a Graphics object, which contains information about where and how we can draw.  In this example, we choose to draw the text "Hello World!" at coordinates (50,25) by calling the drawString method.

We can compile our program by typing

    javac HelloWorld.java

This produces a file named HelloWorld.class.  We now embed our applet in an HTML file, Hello.html, and we can run it by typing

    appletviewer Hello.html

We can also view Hello.html in a Java-enabled browser.
 

HelloWorld.java

import java.applet.Applet;
import java.awt.Graphics;
 
public class HelloWorld extends Applet {
    public void paint(Graphics g) {
        g.drawString("Hello world!", 50, 25);
    }
}
 

Hello.html

<HTML>
<HEAD>
<TITLE> A Simple Program </TITLE>
</HEAD>
 
<BODY>
Here is the output of my program:
<APPLET CODE="HelloWorld.class" WIDTH=150 HEIGHT=25>
</APPLET>
</BODY>
</HTML>
 

4. Java Basics

Java Data Types

Java has two main categories of data types: primitive data types and reference data types.  Java does not support the notion of pointers.

Here is a list of primitive data types.
 

Primitive data type Size in bytes/Format
byte 1
char, short 2
int, float  4
long, double 8
boolean true or false
 
Reference data types include arrays and classes.  Here is an example of a Line class.

Line.java

class Line {
 
    private int miX1, miX2, miY1, miY2;

    public Line() {
        miX1 = miX2 = miY1 = miY2 = 0;
    }

    public Line(int iX1, int iX2, int iY1, int iY2) {
        miX1 = iX1;
        miX2 = iX2;
        miY1 = iY1;
        miY2 = iY2;
    }
}
 

Creating Objects - Constructors

In Java, objects of user defined data types must be dynamically created.  In the following example, the first statement declares a Line object, but does not actually create it.  The second statement uses the new operator to actually create the object.  Note the subtle differences between Java and C++.

Line line;                        // Declaration of object (does not create object.)
line = new Line();            // Instantiation of object.
 

Garbage Collection and Finalization

The Java runtime system provides a garbage collector, which periodically destroys any unused objects in dynamic memory.  The Java garbage collector uses a mark-sweep algorithm.  The dynamic memory is first scanned for referenced objects and then all remaining objects are treated as garbage.  Prior to deleting an object, the garbage collector will call the object's finalizer, which allows the object to perform an orderly cleanup of any associated system resources, such as open files.

Finalization and garbarge collection happen asynchronously in the background.  It is also possible to force these tasks to occur using the System.runFinalization() and System.gc() commands.

A finalizer has the form

    protected void finalize() throws Throwable {
           ...
          // Clean up code for this class here.
          ...
         super.finalize();  // Call the superclass's finalizer (if provided.)
   }

Inheritance

As indicated above, the extends keyword allows us to write classes that inherit the properties and methods of another class.

    class SubClassName extends SuperClassName {
        ...
    }

If a superclass name is not specified, the superclass is assumed to be java.lang.Object.   Also, note that each class can have only one immediate superclass i.e. Java does not support multiple inheritance.
 

Packages

A package is a group of related classes or interfaces.  Each package defines its own namespace. Thus, two different packages may contain classes with the same name.

We can create a package by placing a package statement at the top of every source file that defines a class belonging to the package.  We may later use the classes in the package by placing an import statement at the top of the source file that needs to access the classes in the package.
 

graphics/Line.java  (Path of the file is relative to the CLASSPATH environment variable.)

package graphics;       // Class Line belongs to package graphics.

public class Line {      // The public class modifier makes this class accessible outside the package.
     ...
}

MyTest.java

import graphics.*;     // Provides access to all public classes in package graphics.

class MyTest {
    public static void main(String[] args) {
         Line line;
         graphics.Line line2;   // Can be used for conflict resolution if two packages have a Line class.
         line = new Line(0,0,3,4);
         line2 = new Line();
    }
}
 

If a package name is not specified for a class, then the class belongs to the default package.  The default package has no name and it is always imported.

Here are some core Java packages:

 

Member Access Specifiers

There are four types of member access levels: private, protected, public and package.  Note that, unlike C++, we must specify access levels on a per-member basis.

class Access {
    private privateMethod();                      // Access level is "private".
    protected protectedMethod();               // Access level is "protected".
    public publicMethod();                        // Access level is "public".
    packageMethod();                               // Access level is "package".
}
 
 
Access specifier Acessible by
Class definition Subclass definition Rest of Package Rest of World
private Yes No No No
protected Yes Yes Yes No
public Yes Yes Yes Yes
none i.e. package  Yes No Yes No
 

Instance and Class members

As in C++, we can have instance members or class members.  A class member is declared using the static keyword.

class MyPoint {
    int x;
    int y;
    static int x_origin;
    static int y_origin;
}

In this example, every object has its own x member, however, all objects share a single x_origin member.
 

Constant Members

A final variable is one whose value cannot be changed e.g.

class Avo {
       final double AVOGADRO = 6.023e23;
}
 

Class modifiers

We have already seen some examples of member modifiers, such as public and private.  Java also allows us to specify class modifiers.

Interfaces

An interface declares a set of methods and constants, without actually providing an implementation for any of those methods.  A class is said to implement an interface if it provides implementations for all of the methods declared in the interface. e.g.

interface Collection {
      int MAXIMUM = 100;
      void add(Object obj);
      void delete(Object obj);
}
 
class Stack implements Collection {
      void add(Object obj) {
            . . .
      }
      void delete(Object obj) {
            . . .
     }
}

How does an interface differ from an abstract class?
 

Exceptions and Error Handling

What happens when a program encounters a run-time error?  Should it exit immediately or should it try to recover?  The behavior that is desired may vary depending on how serious the error is.  A "file not found" error may not be a reason to terminate the program, whereas an "out of memory error" may.  One way to keep track of errors is to return an error code from each function.  Exceptions provide an alternative way to handle errors.

The basic idea behind exceptions is as follows.  Any method with the potential to produce a remediable error should declare the type of error that it can produce using the throws keyword.  The basic remediable error type is class Exception, but one may be more specific about the type of exception that can be thrown e.g. IOException refers to an exception thrown during an input or output operation.  When an exception occurs, we use the throw keyword to actually create the Exception object and exit the function.

Code that has the potential to produce an exception should be placed within the try block of a try-catch statement.  If the code succeeds, then control passes to the next statement following the try-catch statement.  If the code within the try block fails, then the code within the catch block is executed.  The following example illustrates this.
 

class LetterTest {
      char readLetter() throws Exception {        // Indicates type of exception thrown.
             int k;
 
             k = System.in.read();
             if (k < 'A' || k > 'z') {
                   throw new Exception();                  // Throw an exception.
             }

             return (char)k;
      }

      public static void main(String[] args) {
             LetterTest a = new LetterTest();

             try {
                    char c = a.readLetter();
                    String str;
                    str = "Successfully read letter " + c;
                    System.out.println(str);
              }
             catch (Exception e) {                           // Handle the exception.
                    System.out.println("Failed to read letter.");
             }
      }
}
 

Note: in addition to the Exception class, Java also provides an Error class, which is reserved for those kinds of problems that a reasonable program should not try to catch.