Inhaltsverzeichnis

Java

Java Plumbing 2010-03-16 16:25 Stefan Beckert
Java Web Programming 2010-04-30 14:19 Stefan Beckert
Apache Click 2010-04-30 14:22 Stefan Beckert
Apache Tomcat 2010-04-30 14:23 Stefan Beckert
Standalone Javascript 2010-08-16 12:06 Stefan Beckert

Java Versions and Compatibility

Tested all on Slack 10.0 2005-09

Bytecode Generation with javac 1.5

Source 1.4 Source 1.5
IYES INO → Bytecode 1.4
IYES IYES → Bytecode 1.5

Bytecode Execution with different VM's

Bytecode 1.4 Bytecode 1.5 Bytecode 1.6
IYES INO INO → VM 1.4
IYES IYES INO → VM 1.5
IYES IYES IYES → VM 1.6

main method

public static void main(String[] args) {}
public static void main(String[] args) throws XXXException {}
public static void main(String args[]) {
    //throw new RuntimeException();
    System.exit(3);
}

Declaration modifiers

Mini Glossary

nonstatic static
variable instance variable class variable
method instance method class method

See also java/javaOO/classvars.html

static

final (or const)

(from Java Tutorial Sun)

The concept of const objects and const methods is missing in Java. A workaround
is to use an Interface, see Faqs of de.comp.lang.java

final objects

public class Tester {
    public int i= 1;
 
    public static void main(String args[]) {
        final Tester b = new Tester();
        Tester       c = new Tester();
        b.i = 2;  // works always
        //b = c;  // Error: cannot assign a value to final variable b
        c   = b;  // works
    }
}

Rich Internet Applications

FIXME Whole secton is obsoete. See Java Plumbing instead!

Java Web Start

This might help: http://www.developer.com/java/web/article.php/3828811

Applets

Embedding in HTML

Easiest is to use the applet tag

See also:

Code Template

It is recommended to use JAppled instead of Applet. Therefore the rest of this section is obsolete. An example for the use of JAppled is provided below.

import java.applet.Applet; // *1
public class HelloWorld extends Applet { // *1
    public void init() { . . . }    // *2
    public void start() { . . . }   // *2
    public void stop() { . . . }    // *2
    public void destroy() { . . . } // *2
    public void paint(Graphics g) { g.drawString("Hello world!", 50, 25); } // *3
}
  1. has to be subclassed from Applet
  2. called by the browser, may be overwritten
  3. inherited from java.awt.Container

see also Java Tutorial Sun: Lesson: Overview of Applets

Events

General

The folling example code is part of the constructor of a subclass of JFrame:

JButton jb= new JButton("Click me");
jb.addActionListener(   new ActionListener() { // an anonymous object is passed here
                            public void actionPerformed(ActionEvent e) {
                                System.out.println("'jb' button pressed");
                            }
                        }
                     );

To find the appropriate addXxxListener() method of the event source, see Java in a Nutshell (maybe obsolete) or search for such methods in the reference documentation of the event source and its superclasses or look at „Using Swing Components“ in the Java Tutorial

FIXME Any better idea?

canClose()

public class Klasse extends JFrame {
    public Klasse() {
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
            // see apiSpecSun/api/javax/swing/JFrame.html & javaTutSun/uiswing/compontents/frame.html
        addWindowListener(new MyAppCloser());
    }
    // Event handler for closing the application window as inner class:
    class MyAppCloser extends WindowAdapter {
        public void windowClosing(WindowEvent we) {
            if (
                JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(
                    null, // default Frame
                    "confimation question", "Title", JOptionPane.YES_NO_OPTION
                )
            ) System.exit(0);
        }
    }
}

Strings

general

Class String        // constant string, can't be changed
Class StringBuffer  // mutable string, thread save
Class StringBuilder // mutable str., for single thread only, faster, since V1.5

String2Number Conversion

byte ix= Byte.parseByte("47");
int ix= Integer.parseInt("4711");
 
String s= ""+ 4711;
String s= new Integer(4711).toString();
String s= String.valueOf(4711);

Inheritance

FIXME

Constructors and Initialisation

Default Constructor

If any constructor is provided, than also the default constructor (= constructor without arguments) has to be provided. Tested 2005-09-09 on JDK 1.5

Multiple Constructors

public class Klasse {
    private int i, j;
    public Klasse(int i, int j) { this.i=i; this.j=j; }
    public Klasse() { this(0,0); }
}

Static Initialization Block

Acts like a constructor for class members
See Java tutorial for more info
Further example at http://java.sun.com/j2se/1.5.9/docs/guide/language/enums.html

Layout:

class Example {
    static { // static initialization block:
        // This code runs, AFTER super() return, and before the code in the constructor
    }
}

For initializing instance members the constructor should be used!
It would also be possible to use an intstance initializer instead of a constructor, but it is not recommended:

class Example {
    { // intstance initialization block instead of constructor:
        // code
    }
}

Cloning Objects (Copy Constructor)

FIXME See Java Kochbuch p 223

I/O Streams

Byte Streams

InputStream OutputStream
FileInputStream ObjectInputStream FileOutputStream ObjectOutputStream

Character Streams

abstract Reader abstract Writer
BufferedReader InputStreamReader BufferedWriter OutputStreamWriter PrintWriter
FileReader FileWriter
// Abstract class Writer:
Writer append(char c) throws IOException;
void write(int c) throws IOException; // same as above!
void write(String str[, int off, int len]) throws IOException;
 
BufferedWriter(Writer out);
void newLine() throws IOException;//  Write a line separator.
 
FileWriter(File file[, boolean append]) throws IOException;
FileWriter(String fileName[, boolean append]) throws IOException;
 
PrintWriter(File file) throws FileNotFoundException;
PrintWriter(String fileName) throws FileNotFoundException;
PrintWriter(Writer out, boolean autoFlush);
PrintWriter(OutputStream out);
PrintWriter printf([Locale l, ]String format, Object... args); // same as format
void print(allPrimitivesAndObject o);
void println(allPrimitivesAndObject o);
 
// Abstract class Reader:
int read() throws IOException;
 
BufferedReader(Reader in);
String readLine() throws IOException;
 
FileReader(File file) throws FileNotFoundException;
FileReader(String fileName) throws FileNotFoundException;
 
BufferedReader(Reader in);
String readLine() throws IOException

Collections

Overview

Chapter in the Java tutorial

Collection Map
Set List Queue
SortedSet SortedMap
HashSet LinkedHashSet TreeSet LinkedList Vector ArrayList LinkedList, PriorityQueue HashTable LinkedHashMap HashMap TreeMap

Implementations

Methods

// important methods of List:
boolean add(E e)
void add(int index, E element)
boolean contains(Object o)
E get(int index)
int indexOf(Object o)
Iterator<E> iterator()
E remove(int index)
boolean remove(Object o) // Removes the first occurrence
Object[] toArray()
<T> T[] toArray(T[] a)
 
// important methods of Map
boolean containsKey(Object key)
boolean  containsValue(Object value)
V get(Object key)
Set<K> keySet() // Returns a set of the keys
V put(K key, V value) // there is no add!
V remove(Object key)
 
// important methods of Queue:
boolean offer(E o) // Inserts the specified element at the end; also add() possible
E peek() // Retrieves, but does not remove,
E poll() // Retrieves and removes from the beginning; remove() also possible

PriorityQueue must implement the Comparable interface!

Sorting and Searching

Sorting with the Comparable Interface

To sort a List (eg ArrayList) or an array use:

static void Collections.sort(List<T> list);
static void Arrays.sort(allPrimitivesAndObject[] a);

The List interface has no sort method! All elements in the List or array must implement the Comparable interface:

Interface Comparable<T> {
    int compareTo(T o);
}

Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. Keep in mind that compareTo accepts Type T (the generic of the List) wheras equals always only accepts type Object!

Sorting with the Comparator Interface

static void Collections.sort(List<T> list, Comparator<? super T> c);
static void Arrays.sort(T[] a, Comparator<? super T> c); // T is an Object, no primitives!
 
Interface Comparator<T> {
    int compare(T o1, T o2);
}

Searching

static int Collections.binarySearch(List<T> list, T key[, Comparator<? super T> c]);
static int Arrays.binarySearch(allPrimitivesAndObject[] a, allPrimitivesAndObject key);
static int Arrays.binarySearch(T[] a, T key, Comparator<? super T> c);

Call binarySearch() with the array or List as first param, the key as second, and, if not all items implement the Comparable interface, provide a Comparator as 3rd parameter. List or array has to be sorted before binarySearch can be called, otherwise the result is not predictable! If the element is not found, binarySearch returns -length-1

Threads

Basics

A thread owns the locks on one or more objects. The lock of an object can only have one thread as owner.

Only one thread can access the code in a syncronized method or code block at one time. syncronized refers always to an object, not to code; the lock is acquired per object.

Thread States

      Waiting/Blocking/Sleeping
         ↓                 ↑
New → Runnable     ↔    Running → Dead

Verify: As a rule of thumb, only the current thread can bring itself from state Running to another state, other threads can't.

Creating a Thread

Two techniques for providing a run method for a thread:

public class MyRunner implements Runnable {
    public void run() {...}
    public static void main(String args[]) { (new Thread(new MyRunner())).start(); }
}

Important Methods of Class Thread

 public void run() 

To be overwritten! Called by JVM and Should not be called directly. It is possible but doesn't create a real new tread. Represents the main loop of the thread.

Operations on Threads different from the current Thread

 public void start() 

Tell the thread to begin with the execution, i.e. transfer the thread from state New to Runnable. The JVM then calls the run method of this thread.

 public void interrupt(); 

See also JavaTut:Interrupts

public final void join() throws InterruptedException
t.join(); // Example

Causes the current thread to pause execution until thread t terminates. Tread state is Waiting/blocked/sleeping.

(Static) Operations on the current Thread

public static void sleep(long millis) throws InterruptedException;
public static void yield();

These methods Cause the currently executing thread to temporarily pause and allow other threads to execute. A call to those functions affects only the own thread, other threads can't be controlled.

sleep() transfers the thread to state Wating/blocked/sleeping whereas yield() transfers the thread only to Runnable. This means that after calling yield() on the current thread, the VM can immeditatly re-select the thread to run whereas calling sleep(millis) will really stop the thread for at least the millis specified

sleep() does not relaese any locks from objects ⇒ A sleeping threads locks are not available for other treads!

 public static boolean interrupted() 

Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method.
See also interrupt() above and isInterrupted().

Example

import java.io.IOException;
 
class HelloThread implements Runnable {
    public void run() {
        while (true) {
            System.out.println("Hello from HelloThread!");
            try { Thread.sleep(500); }
            catch (InterruptedException e) {
                System.out.println("Got exception in HelloThread!");
                return;
            }
        }
    }
}
 
class SlaveThread implements Runnable {
    Thread m_master;
    SlaveThread(Thread master) {m_master= master;}
    public void run() {
        System.out.println("Im SlaveThread and waiting for HelloThread to terminate");
        try { m_master.join(); }
        catch (InterruptedException e) { return; }
        System.out.println("Good bye from SlaveThread!");
    }
}
 
public class ThreadTest {
    public static void main(String args[]) throws IOException {
        System.out.println("Press Return to stop");
        Thread ht= new Thread(new HelloThread());
        (new Thread(new SlaveThread(ht))).start();
        ht.start();
        System.in.read(); // blocks & waits for a linefeed
        ht.interrupt();
    }
}

Prints:

Press Return to stop
Im SlaveThread and waiting for HelloThread to terminate
Hello from HelloThread!
Hello from HelloThread!
Hello from HelloThread!
[Return]
Got exception in HelloThread!
Good bye from SlaveThread!

An object in the context of threads means data, which is shared among the differnt threads. See also Concept of Semaphores

Description of the Methods

public final void wait() throws InterruptedException
public final void wait(long timeout) throws InterruptedException

Causes the currently executing thread thread to wait (thread state: running → Waiting/blocked/sleeping) until another thread invokes the notify() method or the notifyAll() method for this object, or, in the second version, a specified amount of milliseconds has elapsed. A call to those functions affects only the own thread, other threads can't be controlled.

public final void notifyAll()
public final void notify()

The first version wakes up all threads that are waiting on this object's monitor (Standard use). The second notification method, wakes up a single thread. Because notify doesn't allow you to specify the thread that is woken up, it is useful only in massively parallel applications. See JavaTut > Guarded Blocks

synchronized aMethod() { /* method definition */ }
synchronized (anObject) { /* a code block */ }

The code segments within a program that access the same object from separate, concurrent threads are called critical sections. In the Java language, a critical section can be a block or a method and are identified with the synchronized keyword. The Java platform then associates a lock with every object that has synchronized code.

Example

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
class SharedText {
    private String text= null;
    public synchronized void setText(String text) {
        while(this.text != null) {
            try{ this.wait(); } catch(InterruptedException e) { }
            System.out.println(Thread.currentThread().getName()+ ":setText wakes up");
        }
        this.text= text;
        this.notifyAll();
    }
    public synchronized String getText() {
        String t;
        while((t=this.text) == null) {
            try{ this.wait(); }  catch(InterruptedException e){ }
            System.out.println(Thread.currentThread().getName()+ ":getText wakes up");
        }
        this.text= null;
        this.notifyAll();
        return t;
    }
}
 
class Stdin implements Runnable {
    private SharedText sharedText;
    public Stdin(SharedText sharedText) {this.sharedText= sharedText;}
    public void run() {
        BufferedReader stdin= new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            String t= null;
            try { t= stdin.readLine(); }
            catch(IOException e){ System.exit(1); }
            if (t != null) this.sharedText.setText(t);
            else System.exit(0);
        }
    }
}
 
class Stdout implements Runnable {
    private SharedText sharedText;
    public Stdout(SharedText sharedText) { this.sharedText= sharedText; }
    public void run() {
        while (true) {
            System.out.println("Stdout: "+ this.sharedText.getText());
        }
    }
}
 
public class ThreadTest {
    public static void main(String args[]) {
        SharedText text= new SharedText();
        (new Thread(new Stdin(text), "StdinThread")).start();
        (new Thread(new Stdout(text), "StdoutThread")).start();
    }
}

Misc

Access Specifiers

Default specifier: package

↓Specifier / access from→ same class same package a subclass the world
private IYES INO INO INO
package IYES IYES INO INO
protected IYES IYES IYES INO
public IYES IYES IYES IYES

Inner Classes

nested class
inner class
(regular) inner class method-local inner class anonymous inner class static nested class
class EnclosingClass{
    static class AStaticNestedClass { }
    class InnerClass { } // inner classes are non-static nested classes
}

Arrays, Lists and Loops

Defining an Array

int[] anArray;	       // declare an array of integers
anArray = new int[10]; // create an array of 10 integers
int[] anArray= new int[10]; // composed form: declare & create an array of 10 integers
DateFormat[] dfa = new DateFormat[6];    // composed form
String[] colNames = { "Text", "Topic" }; // shortcut for creating and initializing an array
anArray.length         // get the size of an array, not length() !

To copy an array use System.arraycopy() (see Tutorial, API) or use Arrays.copyOf() (see developer.com)

Walking through

import java.util.*;
class TestArrayAndList{
    public static void main(String[] args){
        String[] myArr= {"eins", "zwei"};
 
        System.out.println("Array: Obsolete: Using length property:");
        for (int ix=0; ix<myArr.length; ix++) { System.out.print(" "+myArr[ix]); }
 
        System.out.println("\nArray: Better: Using Foreach:");
        for (String pos : myArr) { System.out.print(" "+pos);}
 
        List<String> myList = new ArrayList<String>();
        myList.add("one");  myList.add("two");
 
        System.out.println("\nList: Obsolete: Using an iterator:");
        Iterator i = myList.iterator();
        while (i.hasNext()) { System.out.print(" "+i.next()); }
 
        System.out.println("\nList: Better: Using Foreach:");
        for (String pos : myList) { System.out.print(" "+pos);}
    }
}

It is expected that the use of Iterators will diminish: http://www.developer.com/java/print.php/10922_3631061_2

List methods

List<E> list= new ArrayList<E>();
/** Appends the specified element to the end of this list */
boolean add(<E> e);
 
/** Removes the element at the specified position in this list.
    Shifts any subsequent elements to the left (subtracts one from their indices).
    @return the element that was removed from the list.
    */
E remove(int index);
 
/** Replaces the element at the specified position in this list with the specified element.
    @return the element previously at the specified position
    */
E set(int index, E element);

Assertions

Syntax Example

assert a < b;  // or:
assert a < b : "a="+a+" is too big";

see JavaDocSun

When to use

Do not use assertions to check the parameters of a public mehod, throw an IllegalArgumentExcetption intead. (from Java Tutorial)

Generics

Normal "is a" relationship

public void someMethod(Number n){/*...*/}
someMethod(new Integer(10)); // OK
someMethod(new Double(10.1)); // OK

Subtyping and Wildcards

Example: (ERROR means compiler error, not runtime error)

class Gen<T> {
    public void take(T t) {}
}
 
class NumGen<T extends Number> {
    public void take(T t) {}
}
 
public class GenericsTest {
    public static void takeNumGen0(Gen<Number> numGen) {}
    public static void takeNumGen1(Gen<? extends Number> numGen) {}
 
    public static void main(String[] args) {
        Integer i= new Integer(1);
        Double  d= new Double(1.1);
 
        Gen<Number>  numGen = new Gen<Number>();
        Gen<Integer> intGen = new Gen<Integer>();
        Gen<String>  strGen = new Gen<String>();
 
        numGen.take(i); // OK: Integer is a Number
        numGen.take(d); // OK: Double is a Number
        //intGen.take(d); // Obvious ERROR: Double d is not an Integer
 
        takeNumGen0(numGen);  // OK
        //takeNumGen0(intGen); // ERROR: Gen<Integer> is not a Gen<Number> !
        takeNumGen1(numGen); // OK
        takeNumGen1(intGen); // OK: Gen<Integer> is Gen<? extends Number>
        //takeNumGen1(strGen); // Obvious ERROR: Gen<String> is not Gen<? extends Number>
 
        NumGen<Number>  numNumGen = new NumGen<Number>();
        NumGen<Integer> intNumGen = new NumGen<Integer>();
        //NumGen<String>  strNumGen = new NumGen<String>(); // Obvious ERROR: String is not a Number
    }
}

Enum Usage

class Tribool {
    public enum State { UNKNOWN, TRUE, FALSE }
    public State state;
    public Tribool(State state){this.state= state;}
    public Tribool and(Tribool other) {
        Tribool r= new Tribool(State.UNKNOWN);
        if (this.state == State.TRUE) {
            r.state= other.state;
        } else if (this.state == State.FALSE) {
            if (other.state != State.UNKNOWN) r.state= State.FALSE;
        }
        return r;
    }
    public String toString() {return state.toString();}
}
 
public class EnumTest {
    public static void main(String[] args) {
        Tribool t0 = new Tribool(Tribool.State.UNKNOWN);
        Tribool t1 = new Tribool(Tribool.State.UNKNOWN);
 
        System.out.println((t0.and(t1)).toString());
        t1.state= Tribool.State.UNKNOWN; t0.state= Tribool.State.TRUE;
        System.out.println((t0.and(t1)).toString());
        t1.state= Tribool.State.UNKNOWN; t0.state= Tribool.State.FALSE;
        System.out.println((t0.and(t1)).toString());
 
        t1.state= Tribool.State.TRUE; t0.state= Tribool.State.UNKNOWN;
        System.out.println((t0.and(t1)).toString());
        t1.state= Tribool.State.TRUE; t0.state= Tribool.State.TRUE;
        System.out.println((t0.and(t1)).toString());
        t1.state= Tribool.State.TRUE; t0.state= Tribool.State.FALSE;
        System.out.println((t0.and(t1)).toString());
 
        t1.state= Tribool.State.FALSE; t0.state= Tribool.State.UNKNOWN;
        System.out.println((t0.and(t1)).toString());
        t1.state= Tribool.State.FALSE; t0.state= Tribool.State.TRUE;
        System.out.println((t0.and(t1)).toString());
        t1.state= Tribool.State.FALSE; t0.state= Tribool.State.FALSE;
        System.out.println((t0.and(t1)).toString());
    }
}

Further Reading / 2do