Introduction to Java

Getting Started

Java's designers state that it is a simple, robust, object-oriented, architecture-neutral, portable, secure, multithreaded, distributed, interpreted, dynamic, and high-performance language.

A Java program is nothing more than a collection of classes, optionally grouped into packages. Here is a simple program made up of one class that is not part of a package

/**
 * An application class that writes a little greeting.
 */
public class Greeter {

    /**
     * Writes a greeting followed by the first command line argument
     * if one is present.
     */
    public static void main(String[] args) {
        System.out.print("Hello there");
        if (args.length > 0) {
            System.out.print(", " + args[0]);
        }
        System.out.println(".");
    }
}

If you are using Sun's JDK 6 compiler, you would put the above code into the file Greeter.java and compile it like this

javac Greeter.java

This would produce the file Greeter.class, which is only 674 bytes in size (only 580 if you compile with javac -g:none Greeter.java).

Class files are interpreted (run) by a Java interpreter. A Java interpreter can be

(Class files can also be turned into native code before/during interpretation.)

Using Sun's JDK 6, the invocation

java Greeter Alice

interprets (executes) Greeter.class. That's just another way to say "runs the application". Java is said to be "portable" because these class files contain byte codes for an abstract machine which are interpreted, and you can write interpreters for many platforms. There are interpreters running on Solaris, Linux, Windows and many other operating systems as well as consumer electronic devices.

(Note, however, that the "portability of Java" is due only to this Java Virtual Machine, on which class files are interpreted, rather than to the Java language. Hundreds of other languages can be compiled into class files too!)

Classes and Objects

Generally you make classes so that you can make objects of that class.

/**
 * A simple cylinder.
 */
public class Cylinder {
    private double radius;
    private double height;
    public Cylinder(double r, double h) {radius = r; height = h;}
    public double getRadius() {return radius;}
    public double getHeight() {return height;}
    public double getVolume() {return capArea() * height;}
    public double getSurfaceArea() {return 2 * capArea() + sideArea();}
    private double capArea() {return Math.PI * radius * radius;}
    private double sideArea() {return 2.0 * Math.PI * radius * height;}
    public void widen(double factor) {radius *= factor;}
    public void lengthen(double factor) {height *= factor;}
}

The class in this file contains two fields (radius and height), one constructor, and eight methods (getRadius, getHeight, getVolume, getSurfaceArea, capArea, sideArea, lengthen and widen). Compiling this file with Sun's JDK 6 compiler makes the file Cylinder.class. You can give this small class file to a friend who doesn't believe that a glass which is twice as wide as another glass holds four times as much water. Then your friend could write the following:

/**
 * An application that creates some cylinders and calls a couple
 * methods, just for fun.
 */
public class VolumeChecker {
    public static void main(String[] args) {
        Cylinder c1 = new Cylinder(1, 4);
        Cylinder c2 = new Cylinder(1, 4);
        Cylinder c3 = c2;
        c2.widen(2);
        System.out.println("Volume of first glass is " + c1.getVolume());
        System.out.println("Volume of second glass is " + c2.getVolume());
        System.out.println("Volume of third glass is " + c3.getVolume());
    }
}

Here we made two objects of the class Cylinder. Objects are created with the "new" operator. The first object is referenced by the variable c1 while the second is referenced by the variables c2 and c3. Never confuse the term 'variable' with the term 'object'. They are completely different things! See how we have three variables but two objects:

cylindervarobj.png

The "new" operator in Java allocates memory for the cylinder objects, but the programmer never explicitly deallocates memory for objects. The Java runtime automatically does garbage collection of objects that are no longer referenced.

Program Structure

Logically, Java programs are made up of classes that are grouped into packages. Physically, your program is written in a collection of source code files. Almost every Java compiler in the world forces this organization:

javastructure.png

Each class definition is compiled into a .class file. Packages can be split over several source code files, but each class has to be wholly contained in a file.

javacompilation.png

If you don't give a package declaration your class(es) will go in the "default package". This is considered unprofessional and stupid, but it's fine when you are learning or experimenting.

Standard Libraries (APIs)

People have written millions of classes since Java was created, but a few thousand of them have been collected into one of Java's standard, or core, APIs. The APIs vary by platform, of which there are three:

In Java SE 6, there are 3777 classes in the standard library, grouped into 202 packages. Here's an example that uses six of these standard classes.

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * An application which displays each of the times on a twelve-hour
 * clock that the hour and second hands make an angle of 180 degrees.
 */
public class AntiparallelClockHandsComputer {
    public static void main(String[] args) {
        long midnight = new GregorianCalendar(0, 0, 0).getTimeInMillis();
        for (int i = 0; i < 12; i++) {
            Date d = new Date(midnight + Math.round((0.5+i) * 43200000/11.0));
            System.out.println(new SimpleDateFormat("hh:mm:ss").format(d));
        }
    }
}

Our AntiparallelClockHandsComputer class uses the classes

    java.lang.String
    java.lang.System
    java.lang.Math
    java.text.SimpleDateFormat;
    java.util.Date;
    java.util.GregorianCalendar;

The import statements at the top of the source file allow us to avoid specifying the full name of these classes throughout our code. Note that import statements are never necessary, they are simply a convenience. (Also note that classes from java.lang don't have to be mentioned in import statements.)

Besides the 202 "core" packages, there are many hundreds of additional packages that you can buy or download for free.

The core classes are, as a rule, bundled into the file rt.jar which your compiler always knows how to find.

Exercise: Find rt.jar on your computer.

Evolution

Java has evolved over time. Java SE has evolved like this:

Version Released Packages in
Core API
Classes in
Core API
What's New
1.0 1995 8 210  
1.1 1997 22 477 I/O design flaws fixed; inner classes; internationalization; AWT enhancements; JavaBeans API; JARs; RMI; reflection; JDBC; JNI; ...
1.2 1999 59 1524 Swing; collections; Permissions, policies, certificates, signers; Java2D; accessibility API; extensions framework; RMI enhancements; reference objects; sound; ...
1.3 2000 76 1840 JNDI; Java Sound; Swing and Java2D enhancements; Security enhancements; Networking enhancements; Improved serialization support; Input method framework; timers; ... (Sun released the HotSpot VM during this time.)
1.4 2002 135 2723 New IO library (NIO); assertions; XML, crypto, SSE, authentication added to core API; Image IO; Java Print Service; many Swing enhancements; Logging API; WebStart; JDBC 3.0; Chained Exceptions; IPv6; Unicode 3.0; Regexes; ...
5.0 2004 166 3279 Generics; better for statement; annotations; enumerations; sophisticated concurrency packages; autoboxing; varargs; static import; Unicode 4.0 (uh-oh); tons of library enhancements; ...
6.0 2006 202 3777 Scripting languages can be embedded; XML and web services; JDBC 4; Many GUI enhancements (e.g. for tables and trees); monitoring and management, programmatic access to compiler; pluggable annotations; improved desktop deployments; a few more security apis; ...

Some Useful Facts

Language Reference

The official reference for the language is The Java Language Specification. It contains a nice one-page syntax of the language.

Some useful items follow here anyway:

Reserved Words

Reserved words are words that cannot be used as identifiers.

        abstract    continue    for           new          switch
        assert      default     if            package      synchronized
        boolean     do          goto          private      this
        break       double      implements    protected    throw
        byte        else        import        public       throws
        case        enum        instanceof    return       transient
        catch       extends     int           short        try
        char        final       interface     static       void
        class       finally     long          strictfp     volatile
        const       float       native        super        while

Note that false, true, and null are not reserved words, but they are literals of built-in types, so you can't use them as identifiers even if you tried.

Statements

The statements are

Operators

Here are the Java operators, presented from highest to lowest precedence.

OperatorsOperand TypesAssociativityArityDescription
++, --
+, -
~
!
(typename)
arithmetic
arithmetic
integral
boolean
any
R 1 increment and decrement
unary plus and minus
bitwise complement
logical not
cast
*, /, % arithmetic L 2 multiplication, division, remainder
+, -
+
arithmetic
string
L 2 addition, subtraction
concatenation
<<
>>
>>>
integral L 2 left shift
right shift with sign extension
right shift with zero extension
<, <=, >, >=
instanceof
arithmetic
object/type
L 2 arithmetic comparison
has type
==
!=
==
!=
primitive
primitive
object
object
L 2 equal values
different values
refer to same object
refer to different objects
& integral
boolean
L 2 bitwise AND
boolean AND
^ integral
boolean
L 2 bitwise XOR
boolean XOR
| integral
boolean
L 2 bitwise OR
boolean OR
&& boolean L 2 short-circuit boolean AND
|| boolean L 2 short-circuit boolean OR
?: boolean/any/any R 3 if-then-else
=
*=, /=, %=, +=, –=
<<=, >>=, >>>=
&=, ^=, |=
variable/any
variable/arithmetic
variable/integral
variable/integral
R 2 assignment

Types

Every expression in Java has a value and a type. There are two kinds of types.

The value of an expression of a primitive type is the primitive entity (like true or 759 or 4322.95 or '@'), but the value of a variable of a reference type (object or array) is either null or a reference to the object or array, NOT the object itself.

referenceexample.png

Primitive entities can just be written down; objects (and arrays) are only created using "new."

Important: Remember that variables of non-primitive types contain references; therefore, the "=" and "==" operators DO NOT copy and test the equality of object values. (There may be clone() and equals() methods available, or you can define these if needed.)

This example shows how variables of primitive types differ from variables of reference types:

float x;
x = 3;                          // value 3 stored in x
float y = x;                    // value 3 stored in y
y = 4;                          // after this x is still 3

Cylinder c1;                    // just declares a variable
c1 = new Cylinder(1, 1);        // now we have a cylinder created
Cylinder c2 = c1;               // does NOT create a new cylinder
c2.widen(2);                    // exactly the same effect as c1.widen()
c1 = null;                      // the cylinder still exists

double d = c1.getRadius();      // OOPS!! Throws a NullPointerException

double r = c2.getRadius();      // This is perfectly fine: c2 isn't null
c2 = null;                      // Now the object is unhooked.  It is
                                // "garbage" and the runtime system
                                // will eventually reclaim the storage.

An interesting note: variables which are fields of a class are automatically initialized in Java: for primitive types they are automatically initialized to 0 for numbers and false for booleans; for objects they are initialized to null.

Exceptions

There are dozens of "throwable" classes in the Java Core API. Throwables are either errors or exceptions. Exceptions are either runtime exceptions (a.k.a unchecked exceptions) or checked exceptions.

In many cases you will define your own exceptions, but if your situation can use a pre-existing one, please do so. The most common pre-defined exceptions that you will have occasion to throw are:

Class Used when
IllegalArgumentException Arguments passed to a method don't make sense.
IllegalStateException An object isn't in the right state to execute this method.
NoSuchElementException You're trying to remove an element from an empty collection, or looking for a specific item that isn't there.
UnsupportedOperationException The requested operation isn't implemented

Garbage Collection

Programmers have a couple responsibilites when it comes to using memory and other resources efficiently:

More Notes