WJB-275A: Java programming Language
The Java Runtime Environment
Class loader: Maintains classes loaded from the local file system in a separate namespace. For duplicate classes it will prefer files from the local file system to prevent spoofing.
Class loader -> Bytecode verifier: Checks to make sure the byte code conforms to the specification and does not violate system integrity.
Class loader -> Bytecode verifier -* Interpreter: Reads the byte code and issues commands to the operating system.
Class loader -> Bytecode verifier -* JIT Compiler: Compiles the bytecode into native format so it does not have to be interpreted every time it is used.
The main
method is the entry point into our application.
public static void main(String[] args)
To compile our application use ``javac``, the Java compiler. The compiler will
automatically build dependencies e.g. if ``TestGreeting.java`` depends on
``Greeting.java``, the compiler will build them both with this command:
javac TestGreeting.java
To run the application:
java TestGreeting
Note: We do not append .class
to the application name.
The -d
option specifies the output folder (where we want our classes to be
output):
javac -d ../classes shipping/domain/*.java
To create a jar
file:
Create a text file containing the name of your main class (in this example the file is called
tempfile
and contains the following:Main-Class: mypackage.MyMainClass
Create the
jar
file:jar cmf tempfile MyProgram.jar
To run the
jar
file:java -jar /path/to/file/MyProgram.jar
Object-Oriented Programming
Abstraction: Hiding the details of how something gets done.
Analysis: describes what the system needs to do.
Design: describes how the system does it.
Frameworks and APIs: Groups of objects that support a complex activity.
Encapsulation: Data hiding. private
attributes, public
access
methods.
Inheritance:
Polymorphism:
Class:
Class names: should contain whole words; avoid acronyms and abbreviations.
Class attributes.
Also known as a data member, an instance variable or a data field.
If we don’t declare an initial value a default value will be assigned.
Class methods:
Also know as a function or procedure.
Constructors:
Cannot return a value.
If you do specify the
void
keyword the constructor will become a method!If you do not add a constructor to the class, the compiler will create a one which does nothing. If you do add a constructor, the compiler will not create one.
UML:
+
ispublic
-
isprivate
Packages: Group logically related classes.
import
: Just allows access to other classes (tells the compiler where to
find classes). Does not cause the compiler to load anything additional into
memory, or affect the class file.
WJ-2752A: Understanding the Building Blocks of Java(TM) Technology
Identifiers (Names)
Must start with either:
An uppercase letter.
A lowercase letter.
An underscore.
a dollar sign…
After the initial character you may also use numbers (in addition to the aforementioned characters).
Java keywords may not be used.
Begin each name with a lower case letter.
Subsequent words within the name should be capitalized e.g. firstName.
Data Types
int
Literal077
= Octal,OxBAAC
= Hex.char
16-bit Unicode.float
Literal3.0f
double
Literal3.0
(without thef
).boolean
Must assigntrue
orfalse
(must not assign1
or0
).String
is not a primitive, it is an object.
Reference and Primitive Types
Reference types… a reference to an object. The object is created in heap memory, the address of the object is stored in the reference variable (in stack memory). References can be copied around. You can have more than one reference to a particular object.
Primitive types store the actual value in memory (not a reference).
In Java, all objects are passed by value (a copy is made of the variable), whether it is a primitive or an object reference.
You can use the same name for an argument (or local variable) as an instance variable. Instance variables are identified by prepending
this
to the variable. The local variable or argument will take precedence unless the instance variable is prepended withthis
:private int day = 1; public MyClass(int day) { this.day = day; }
Conventions
Packages: nouns in lower cases e.g.
package shipping.objects
.Classes and Interfaces: nouns in mixed case with the first letter of each word capitalised e.g.
class AccountBook
.Method names: verbs, in mixed case, with the first letter in lower case. Capital letter separate words. Limit the use of underscores.
Variables: Mixed case, lower case first letter, words separated by capital letters. Limit the use of underscores. Avoid using the dollar sign (it has a special meaning to inner classes). e.g.
currentCustomer
. Avoid single character names except for temporary throwaway variables (loop control).Constants: Primitive constants should be all upper case with the words separated by underscores. Object constants can use mixed case letters. e.g.
HEAD_COUNT
.Braces: Use braces around all statements, even single line statements.
Spacing: Place only a single statement on any line.
Indentation: Use two or four-space indentations to make your code readable.
Comments: Use comments to explain code segments that are not obvious.
Variable Initialisation
Local variables do not get a default value. If they are not initialised we will get a compile error.
Instance and class variables (static
) get initialised to:
0
for numeric typesfalse
for the boolean type\\u0000
for thechar
typenull
for object reference values (the variable points to nothing).
Operators
String concatenation:
One argument must be a
String
object.String objects are immutable. Once they are created they can never be changed.
Casting
Promotion (automatic casting).
Varibles are promoted automatically to a longer form e.g. Assigning an
int
to along
.Casting (manual casting)
Override the compiler warning of loss of precision.
Branching Statements
switch
Can only be used with the
byte
,short
,char
andint
data types.The
break
statement stops the program from falling through to the nextcase
statement.default
if none of the*case
values match.
for
Expressions
for (<init_expr>; <test_expr>; <alter_expr>)
alter_expr
the alteration expression. It will be evaluated at the end of the loop.while and do/while:
while (<test_expr>)
If the test expression evaluates to
true
.Special Loop Flow Control:
break
, force us to leave the loop immediately.continue
, leaves the loop body and jumps straight to the test expression.break labels
, if you want to break out of nested loops, label the outer loop and issue thebreak labels
statement. The code will jump straight to the test expression of the outer loop:outer: do { statement1; do { statement2; if (condition) { break outer; } statement2; while (test_expr); statement2; while (test_expr);
continue labels
does the same asbreak labels
, but continues rather than breaking.
Arrays
To declare an array (both forms are fine):
type [] array_identifier
type array_identifier []
Creating arrays:
array_identifier = new type[length];
Initializing Arrays:
array_identifier[index] = value;
or:
type [] array_identifier = {comma-separated-list};
type array_identifier [] = {comma-separated-list};
Multidimensional Arrays
Declaring multidimensional arrays:
type [][] array_identifier
type array_identifier [][]
Creating multidimensional arrays:
array_identifier = new type[number_of_arrays] [length]
Note: Java multidimensional arrays are not the standard implementation, we specify the number of arrays. We create several one dimensional arrays rather than a true multidimensional array.
Array attributes:
int i = myArray.length;
Enhanced for loop (Java 1.5 and later):
for(int value : myArray)
System.out.println(value);
Resize array:
In Java, arrays cannot be resized. You can however reuse the array reference
variable. We can use the System.arraycopy
method to copy arrays.
Class Design
Single Inheritance
extends
is a e.g.
../../../images/howto/uml/inheritance-sun.gif
Manager is an Employee
Director is a Manager is an Employee
General (or abstract) classes appear at the bottom of the tree.
Access Control
Modifier |
Same Class |
Same Package |
Subclass |
Universe |
---|---|---|---|---|
|
Yes |
No |
No |
No |
default |
Yes |
Yes |
No |
No |
|
Yes |
Yes |
Yes |
No |
|
Yes |
Yes |
Yes |
Yes |
Overriding Methods
A subclass method may invoke a superclass method using the super
keyword.
super
is used to refer to data attributes and methods.Behaviour invoked does not have to be in the superclass; it can be further up in the hierarchy.
public String getDetails() {
return super.getDetails()
+ "\nDepartment:" + department;
Polymorphism
“many forms”…
Collections
homogeneous |
collections of objects with the same class type. |
heterogeneous |
collections of objects with different class types. |
Polymorphic Arguments…
instanceof
Casting
../../../images/howto/java/learning/instanceof.gif
Casts upward in the hierarchy are done implicitly.
Downward casts must be to a subclass and are checked by the compiler.
Variable Arguments
Java 1.5 or later…
average(1, 2);
average(1, 2, 3);
public int average(int ... nums) {
int sum = 0;
for (int x : nums) {
sum += x;
}
return sum;
}
Overloading Constructors
…a constructor can call another constructor using the
this
call (thethis
call must be the first line of the constructor):public Employee(String name) { this(name, BASE_SALARY); } public Employee(String name, double salary) { System.out.println("Name [" + name + "] Salary [" + salary + "]"); }
Constructors are not inherited.
When one class
extends
from another class, a constructor from each level of the class hierarchy must be called. Thesuper
command must be used to tell the compiler which constructor to call at the level above us (thesuper
call must be the first line of the constructor).If the superclass constructor is not invoked explicitly, Java will insert a call to
super()
, the superclass’s no-args constructor.The constructors in a class hierarchy are called from the top, down. This is because classes further down the hierarchy might want to use some of the data which has been initialised in the super class.
The Object class.
A class declaration with no
extends
clause impliesextends Object
.If two objects are equal they must return the same hash code (but this does not mean that two equal objects will return the same hash code).
Wrapper Classes
The primitive data types are not objects - but each data type has an associated wrapper class e.g. the
int
data type hasInteger
wrapper class).Storing the primitive object in the wrapper class is called “boxing”.
To get the primitive data type out of the wrapper object, call the associated method, e.g.
Integer age = new Integer(43); // boxing int i = age.intValue(); // unboxing
Java 1.5 and later can perform autoboxing and autounboxing:
Integer age = 43; // autoboxing int i = age; // autounboxing
To convert a
String
to a primitive object:int i = Integer.parseInt("43");
To convert a
String
to the associated wrapper object:Integer i = Integer.valueOf("43");
Advanced Class Features
The static
keyword.
Is an attribute or method shared among all instances of that class.
static initialisation blocks. Is called when the class is first loaded into memory:
public static int counter; static { counter = 43; }
The final
modifier.
If applied to a class, you may not
extend
the class.If applied to a method declaration, you may not
override
that method in a subclass.If applied to a variable:
A final variable is a constant (and cannot be changed).
If applied to a class attribute, the assignment can occur independently of the declaration. A “blank final” instance attribute must be set in every constructor.
private final long customerId = 23;
or:
private final long customerId; public Customer() { customerID = createId(); }
A “blank final” method variable must be set in the method body before being used.
Enumerated Types
Java 1.5 and above:
public enum Colour {
RED,
BLUE
}
An
enum
can be thought of as like a class type.enum
’s can have constructors, attributes and methods:public enum Colour { RED("Red"), GREEN("Green"); private final String description; private Colour(String description) { this.description = description; } public String getDescription() { return description; } } public static void main(String[] args) { // Will print "RED Red": System.out.print(Colour.RED + " " + Colour.RED.getDescription()); }
Static Imports
Java 1.5 and above:
Imports static members from classes, allowing them to be used without class qualification:
import static com.sample.Colour.RED;
System.out.print(RED + " " + RED.getDescription());
Abstract Classes
Only subclasses of
abstract
classes can be created.Do not provide an implementation (or body) for abstract methods.
Subclasses must provide implementations of
abstract
methods before they can be created.
Interfaces
A class can
extend
another class and implement an interface at the same time.
Exceptions
Exception Categories:
Type |
Represented by |
Note |
---|---|---|
Checked |
|
Conditions that readily occur e.g. File not found. |
UnChecked |
|
Probable bugs |
UnChecked |
|
Fatal - Typically the program will exit. “Nothing we can do about them”. |
Exception Categories
../../../images/howto/java/learning/exception-hierarchy.gif
“handle or declare rule”, either handle the exception using a
try
,catch
block or declare that you throw that type of error (using thethrows
statement).When you override a method, you can throw the same exception, a subclass of the original exception or no exception.
To create your own exception class, extend the
Exception
class (or one of it’s subclasses) (checked), or theRuntimeException
class (unchecked).
Assertions
Use assertions to document and verify the assumptions and internal logic of a single method.
Do not use assertions to check the parameters of a public method.
Only turned on during development.
Sample code:
assert(x == 0); assert false : "Unknown colour";
If assertion checking is disabled (the default), the code runs as fast as if the check was never there.
To enable assertions:
java --enableassertions MyProgram java -ea MyProgram
Assertion checking can be controlled on a class, package or package hierarchy basis.
Text Based Applications
System Properties
System properties are a feature that replaces the concept of environment variables (which are platform specific).
The
System.getProperties
method returns aProperties
object.The
System.getProperty
method returns aString
representing the value of the named property.Use the
-D
option to include a new property.Sample code:
import java.util.Properties; import java.util.Enumeration; public class TestProperties { public static void main(String[] args) { Properties props = System.getProperties(); Enumeration propNames = props.propertyNames(); while (propNames.hasMoreElements()) { String propName = (String) propNames.nextElement(); String property = props.getProperty(propName); System.out.println("property " + propName + " is " + property); } } }
Console I/O
Variable |
Action |
I/O |
Object of type |
---|---|---|---|
|
writes to |
Standard output |
|
|
reads from |
Standard input |
|
|
writes to |
Standard error |
|
The
InputStreamReader
reads in characters one by one and converts them to unicode characters.To read a line at a time, we wrap the
InputStreamReader
in aBufferedReader
object.InputStreamReader ir = new InputStreamReader(System.in); BufferedReader in = new BufferedReader(ir);
Java 1.5 has added the
System.out.printf
method (also available in theString.format
method (%n
is the newline character):System.out.printf("%s is %d years old.%n", "Peter", 43); String s = String.format("%s is %3d years old.", "Martin", 16);
The
Scanner
API provides a formatted input function:java.util.Scanner s = new java.util.Scanner(System.in); String param = s.next(); int value = s.nextInt(); s.close();
The
Scanner
API can be used with console input streams as well as file or network streams.
Files and File I/O
The
FileReader
object reads characters, theBufferedReader
object can read one line at a time (seeInputStreamReader
above):BufferedReader in = new BufferedReader(new FileReader(file));
The
FileWriter
object will write one character at a time, we wrap this object in aPrintWriter
object which will allow us to use theprint
andprintln
methods to write one line at a time:PrintWriter out = new PrintWriter(new FileWriter(file));
The Collections API
|
unordered |
no duplicates |
|
|
ordered |
duplicates allowed |
|
Generics
If we want the compiler to show us where we should be using generics:
javac -Xlint:unchecked MyProgram.java
The
ListIterator
interface of aList
allows us to iterate backwards (using thehasPrevious
andprevious
methods) as well as forward.Java 1.5 and above has an enhanced for loop:
public void deleteAll(Collection<NameList> c) { for (NameList nl : c) { nl.deleteItem(); }
…the enhanced for loop can also be used with arrays:
public int sum(int[] array) { int result = 0; for (int element : array) { result += element; }
Building Java GUIs
AWT
Is a first generation GUI API and is later followed by Swing (which has some similarities).
Every GUI component that is displayed on the screen is a subclass of the abstract class
Component
orMenuComponent
.Normally use a
Frame
(a subclass of Window) rather than a window because it includes a title bar, menu bar and minimise/maximise buttons.Normally add components to a
Panel
before adding them to aFrame
.Layout managers are used by default. The default layout manager is the
BorderLayout
:
|
Horizontal.
Default layout for the |
|
Default layout manager for the |
|
Rows and Columns. Components are added from left to right and from top to bottom. The constructor specifies the number of rows and columns. All regions are sized equally. |
|
Like a deck of cards - only one card visible at a time. Use to simulate a tabbed dialog. |
|
Similar to a |
Drawing
The paint method is called every time the component is shown.
Is typically performed by using a Graphics object associated with a component.
Can be performed using the Panel and Canvas classes, although it is possible to draw in any component.
AWT - GUI Event Handling
Event sources - the generator of an event.
Event handlers register with components.
To handle action events, a handler must implement the
ActionListener
interface. Other listener interfaces includeMouseListener
,MouseMotionListener
andWindowListener
.Each listener interface which has more than one method to implement has an associated
abstract
Adapter
class. Thisabstract
class provides empty implementations of every method defined on the interface. If weextend
theAdapter
class we only have to define the methods we are interested in.Event handlers can be defined:
in a standalone handler class.
as part of the class which creates the frame windows and sets up your GUI.
in an inner class. An inner class has access to the
private
data members of the outer class.in an anonymous inner class. Typically used when the code in an event handler is very short.
Sample Code
../../../misc/howto/java/learning/ChatClient.java.txt
AWT - Components
AWT components will have a look and feel which is consistent with the operating system they are running on.
The Swing API (J.F.C) has a distinctive look and feel which can be consistent across platforms. It builds on top of AWT but supplants the operating system components with lightweight versions.
Threads
Threads
Create a class which implements the
Runnable
interface. Therun
method is very similar to themain
method in a single threaded application.public class HelloRunner implements Runnable { int i; public void run() { i = 0; while (i < 5) { System.out.println("Thread loop " + i++); } } } public class ThreadTester { public static void main(String[] args) { HelloRunner r = new HelloRunner(); Thread t = new Thread(r); t.start(); int i = 0; while (i < 5) { System.out.println("Main loop " + i++); } } }
Thread Scheduling:
Thread Scheduling
../../../images/howto/java/learning/thread-scheduling.gif
Terminating a Thread:
public class Runner implements Runnable { private boolean timeToQuit = false; public void run() { while (!timeToQuit) { // Do some work... } } public void stopRunning() { timeToQuit = true; } } public class ThreadController { private Runner r = new Runner(); private Thread t = new Thread(); public void startThread() { t.start(); } public void stopThread() { r.stopRunning(); } } public class ThreadMain { public static void main(String[] args) { ThreadController tc = new ThreadController(); tc.startThread(); // Do some other stuff... tc.stopThread(); } }
Basic Control of Threads:
public class ThreadInfo { public static void main(String[] args) { Thread mt = Thread.currentThread(); if (mt.isAlive()) { String name = mt.getName(); int priority = mt.getPriority(); System.out.println("Name: " + name); System.out.println("Priority: " + priority); mt.setName("New Name"); mt.setPriority(Thread.MAX_PRIORITY); } } }
Putting Threads on Hold
sleep
To move a thread from running into a blocked state, use the
sleep
method:try { Thread.sleep(10); } catch (InterruptedException e) {
join
The
join
method will block until the specified thread completes:public static void main(String[] args) { Thread t = new Thread(new Runner()); t.start(); // Do stuff in parallel with the other thread for a while. try { // Wait here for the timer thread to finish. t.join(); } catch (InterruptedException e) { // t came back early. } // Now continue in this thread. }
yield
I have more work to do… but if someone else would like to use the CPU time… The thread moves to the runnable state and allows other threads to move to the running state.
public class Yield implements Runnable { boolean timeToQuit = false; public void run() { while (!timeToQuit) { // do some stuff... Thread.yield(); } } }
Other Ways to Create Threads
We can inherit directly from the
Thread
class and override therun
method:public class MyThread extends Thread { public void run() { while (true) { // do lots of stuff... try { Thread.sleep(100); } catch (InterruptedException e) { // sleep interrupted. } } } public static void main(String args[]) { Thread t = new MyThread(); t.start(); } }
Note: This is simpler to implement but may not always be the best choice:
Implement |
Extend |
---|---|
Better object-oriented design. |
|
Your class can extend another class. |
|
Consistency? |
Simple code. |
Using the synchronized
keyword
The object lock flag
Every object has a lock, called the “lock flag”. The parameter to the
synchronized
method is the object which we want to lock:public class MyStack { int idx = 0; char[] data = new char[6]; public void push(char c) { synchronized (this) { data[idx] = c; idx++; } } public char pop() { synchronized (this) { idx--; return data[idx]; } } }
Note:
Mark all delicate data
private
.All access to the data through
synchronized
blocks.You may also
synchronized
an entire method.Do not overdo the use of
synchronized
. Only use it where it is needed.
Thread States
The
synchronized
state:Thread States
../../../images/howto/java/learning/thread-states.gif
Thread Interaction
Thread States - wait
../../../images/howto/java/learning/thread-states-wait.gif
The
notify
method will wake up waiting threads.When our thread calls the
wait
method:it gives up it’s lock.
it will block and wait until another thread calls the
notify
method.When notified, it will re-acquire the lock and continue.
To use
wait
andnotify
you must be in asynchronized
block:public synchronized char pop() { char c; while (buffer.size() == 0) { try { this.wait(); } catch (InterruptedException e) { } } c = buffer.remove(buffer.size() - 1); return c; } public synchronized void push(char c) { this.notify(); buffer.add(c); }
Advanced I/O Streams
“stream”: flow of data “from a source” (input) or “to a sink” (output):
Stream |
Byte Streams |
Character Streams |
---|---|---|
Source streams |
|
|
Sink streams |
|
|
Sources and sinks are both “node streams”.
Types of “node streams” are files, memory and pipes between threads or processes:
Type |
Character Streams |
Byte Streams |
File |
|
|
Memory array |
|
|
Memory string |
|
N/A N/A |
Pipe |
|
|
Note: If a class has Reader
or Writer
in it’s name, then we are reading
or writing textual data. If the class has Stream
in it’s name, then we are
reading or writing binary data.
I/O Stream Chaining
../../../images/howto/java/learning/io-stream-chaining.gif
Here are some classes which can be used for stream chaining:
../../../images/howto/java/learning/stream-chaining-options.gif
Networking
The two ends of a conversation are called sockets.
Sockets hold two streams, an input stream and an output stream.
To set-up a network connection, you need the network address (e.g.
server.foo.com
) and port number (from 0 to 65535). Use a port number above 1024.Java Networking Model
../../../images/howto/java/learning/networking-model.gif
Comments
In Java, code is grouped into blocks. The left and right curly braces mark the begin and end of the block: