Java Tips

(also see OOP Basics)

What is a static field?

Static means the variable is shared by all instances of a class. The class does not need to be instantiated prior to accessing one of its static variables. For this reason static variables are also called class variables.

You most often see non-mutable static fields (contants), i.e., their values never change (e.g., Math.PI). The use of non-mutable static fields is common and is not discouraged. You define a non-mutable static field with the key words "static" and "final," as in:

public static final String CERT_PARAMETER = "javax.servlet.request.X509Certificate";

Why should you avoid the use of mutable static fields?

You define a mutable static field by dropping the key word "final." Mutable means the variable is modifiable. Static mutable fields are like global variables in procedural languages but they do not behave the way global variables in procedural languages behave. Java is multi-threaded and every thread accesses the same physical static variables. Multiple threads can represent multiple end users using the same web application. When one of them changes the value of a static variable, it affects all of them. This clearly can have very undesirable and surprising results!

So unless you intend the value of a mutable static field to be shared by all threads, DO NOT USE THEM!


Static methods

Static methods are also shared by all threads but you can protect one user's execution of a static method from being stepped on by another user or thread by using the key work synchronized as in:

public static synchronized Comparator getComparator(String s) ...

The entire snippit of code:

static synchroized method getComparator

When to use instance methods and when to use static methods (These notes have come from Java World):

Instance methods are methods that rely on the state of the specific object instance. Instance methods are tied to a particular instance because the behavior that the method invokes relies upon the state of that particular instance. Whereas, the behavior of a class method (i.e., static method) either depends on a state that all instances of object share at the class level, or is independent of any state at all.

So lets say I wanted to track the number of times a class was instantiated I might create a static mutable field in that class (state that all instances of class share), increment the static mutable field in the class's constructor and then write a public static method to get the number of class instantiations (i.e., this static method depends on the state that all instances of the class share):

private static int instantiations; // state that all instances of ClassName share

public ClassName() {
instantiations++; // incremented everytime the class is instantiated
}
public static int getInstances() { // static method
return instantiations;
}

Any method that is independent of instance state is also a candidate for being declared as static.

Note that I say "candidate for being declared as static." Even in the previous example nothing forces you to declare getInstances() as static. Declaring it as static just makes it more convenient to call since you do not need an instance to call the method. Sometimes you will have methods that don't seem to rely on instance state. You might not want to make these methods static. In fact you'll probably only want to declare them as static if you need to access them without an instance.

Notice in the code samples on this page that the getComparator method needs to be referenced without reference to a specific instance of the class Po.

The difference between using a singleton over a class with static methods boils down to effective object-oriented design. In Java, you CANNOT override static methods. See Java World example of what happens when you attempt to override a static method. In a nutshell, overriding does not work for static if you upcast the instance! With a static you'll get the behavior of whatever class you upcast to. Thus you cannot have polymorphic behavior.


What does the final keyword mean? "This can not be changed, sort of... "

Final classes can not be subclassed (can not be extended).

Final methods can not be overridden.

Final fields can not be changed, i.e., a constant. But this is a bit tricky. It can either be a compile time constant as in public static final double PI = 3.141592653589793d; or a run-time constant as in final int i = (int)(Math.random()*20); or the example from class where the value for the final variable was set in the class's constructors. Also, it can be a primitive whose value can't be changed as in Math.PI or an Object whose pointer can't be changed but whose value can be changed! Strings are immutable which is why the value in final String BLACK = "black"; can be relied upon as consistently as the value of a final primitive.

Final arguments void with(final Gizmo g) { g = new Gizmo(); // illegal because g is final!


NullPointerException (tip on avoiding)

null pointer exception

You can avoid the dreaded NullPointerException by placing the special literal null as the 1st term in the boolean expression instead of as the 2nd term which comes more naturally but does not work becasue the exception is thrown before the comparison can be made. As my husband just pointed out to me, you can tell how popular Java is by how often you get NullPointerException on the web! So all you developers out there - test for null and, when you do, think null == variable!


Initializing variables outside blocks or how to avoid "The local variable output may not have been initialized"

When you want to set the value of a variable within a block of code but you want to reference the variable outside the block of code, it must be BOTH declared and initialized outside the block but you can initialize it to null.

initializing to null


IO Classes

IO Inheritance Tree

(useful ASCII I/O in bold italic)

streams and readers


Java 1.5 Enumeration

enumeration code

The output:

oneDay.toString(): MONDAY
oneDay.ordinal(): 0
oneDay.name(): MONDAY
DaysOfWeek.valueOf(oneDay.toString()): MONDAY
DaysOfWeek.valueOf('MONDAY'): MONDAY
oneDay.toString(): TUESDAY
oneDay.ordinal(): 1
oneDay.name(): TUESDAY
DaysOfWeek.valueOf(oneDay.toString()): TUESDAY
DaysOfWeek.valueOf('MONDAY'): MONDAY
oneDay.toString(): WEDNESDAY
oneDay.ordinal(): 2
oneDay.name(): WEDNESDAY
DaysOfWeek.valueOf(oneDay.toString()): WEDNESDAY
DaysOfWeek.valueOf('MONDAY'): MONDAY
oneDay.toString(): THURSDAY
oneDay.ordinal(): 3
oneDay.name(): THURSDAY
DaysOfWeek.valueOf(oneDay.toString()): THURSDAY
DaysOfWeek.valueOf('MONDAY'): MONDAY
oneDay.toString(): FRIDAY
oneDay.ordinal(): 4
oneDay.name(): FRIDAY
DaysOfWeek.valueOf(oneDay.toString()): FRIDAY
DaysOfWeek.valueOf('MONDAY'): MONDAY

Now to print out the static constants DaysOfWeek.MONDAY - DaysOfWeek.FRIDAY & method valueOf:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
The following DaysOfWeek.valueOf('Monday') will cause an IllegalArgumentException!

Exception in thread "main" java.lang.IllegalArgumentException: No enum const class feb11Class.February4b$DaysOfWeek.Monday

enum and the primitive comparator == versus the class method equals

private DaysOfWeek currentDay = DaysOfWeek.FRIDAY;

enum code

output:

Now print the value of currentDay: FRIDAY

Now test value with == DaysOfWeek.FRIDAY:
== seems to work
Now test value with == DaysOfWeek.FRIDAY:
equals seems to work

So both the class method equals() and the primitive comparator seem to work


String Useful Methods

str4 = a b c d with a length of 9
str4 trimmed = a b c d with a length of 7
Does str4 contain spaces? true
str4.substring(i, i+1) is a
str4.substring(i, i+1) is
str4.substring(i, i+1) is b
str4.substring(i, i+1) is
str4.substring(i, i+1) is c
str4.substring(i, i+1) is
str4.substring(i, i+1) is d

str1 = aBcD and str2 = abcd
str1.equals(str2) = false
str1.length() = 4
str1.charAt(1) = B
str1.compareTo("aBcE") = -1
str1.compareTo("aBcC") = 1
str1.compareTo("aBcD") = 0
str1.indexOf('D') = 3
str1.indexOf("Bc") = 1
str1.indexOf("zz") = -1
str1.concat("efg") = aBcDefg
str2 += "abcd" so str2 = abcdabcd
str2.lastIndexOf("c") = 6
After str3 = str1.toLowerCase(), str3 = abcd
After str3 = str1.toUpperCase(), str3 = ABCD
str1 = aBcD
After str3 = String.valueOf(123); ...
Test if str3.equals("123"): true
FALSE -- str3 != "123"

The last 3 lines were produced by the following code:

str3 = String.valueOf(123);
System.out.println("After str3 = String.valueOf(123); ... ");
System.out.println("Test if str3.equals(\"123\"): " + str3.equals("123")); // str3.equals("123") returns true
if (str3 == "123") System.out.println("TRUE -- str3 == \"123\""); // str3 == "123" returns false String is an Object. Therefore == compares the pointers not the values
else System.out.println("FALSE -- str3 != \"123\"");


Overriding methods from the super class Object

There are methods that all Java objects inherit from their super class Object. Some of these methods were designed to be overriden, specifically:

toString()
toString

equals()
equals

hashCode()
hashcode

If toString() is not overriden it returns a string representation of the object that is pretty useless. For example, if toString() is not overriden:

Po po = new Po("4500718933", "VWR SCIENTIFIC PRODUCTS - ECAT ONLY","24.81"));
System.out.println(po);

would return something like the following:
Po@5eb0a9

Overriding the toString() method that is inherited from Object provides a simple, convenient mechanism for debugging classes during development, by translating object state into text. It can also be used at runtime for passing informative error messages to Exception constructors and assertions.

If the above toString() is in the object, Po, the following would be returned from the statement System.out.println(po);

4500718933 VWR SCIENTIFIC PRODUCTS - ECAT ONLY 24.81

If you don't override equals() and hashCode() no two objects will ever be equal because the default behavior of equals() is to determine if 2 objects are references to the same object on the heap and the default behavior of hashCode() is to give each object on the heap a unique hashcode value. If you override one you must override both because if 2 objects are equal they must return the same hashcode.

If you do override these two methods, you can use Collections.replaceAll() to replace an object in an ArrayList, you can use Collections.binarySearch() against an ArrayList sorted using the compareTo() method to find an object within your ArrayList.


Object Container Classes (aka collection classes)

There are two types of general object container interfaces that form the basis of all these classes:

(1) Map (a group of key-value object pairs, allowing you to look up a value using a key)

java.util.Map - implements Map<key, value> - Keys must be unique. There can be only one value per key, and it may not be null. For example state abbreviation (key), state name (value):

AL, Alabama
AK, Alaska
AZ, Arizona
AR, Arkansas
...

Classes that implement the Map interface (Keys must be unique A Map holds two objects, a key and an associated value, in each slot)

(2) Collection (a sequence of individual elements with one or more rules applied to them)

java.util.Collection - an interface whose classes can hold zero, one. or many instances of some other class(es). (In Java 1.4.2 these are weakly-typed as opposed to Java 5 where you can specify the type of object in your collection. Most of these examples are 1.4.2 code.)

You can add & remove elements
Clear to an empty set
Report their size

Interfaces that extend the Collection interface with the classes that implement these interfaces (A Collection holds one object in each slot)

 

ArrayList is one of the most commonly used classes that implement the Collection interface. In Java 5 you can type your ArrayList (e.g., ArrayList<Po> purchaseOrders = new ArrayList<Po>();) In Java 1.4 you can not type your ArrayList but you can still populate them with other classes (e.g, ArrayList purchaseOrders = new ArrayList(); purchaseOrders.add(new Po());) complete snippit of code:

ArrayList of P.O.s

For purposes of flexibility it would have been better to define my variable purchaseOrders by upcasting it to its interface:

Collection purchaseOrders = new ArrayList<Po>(); // Java 5 code

If your Po class overrides the two methods, equals() and hashCode(), which it inherited from Object, then you can replace Po items in your ArrayList purchaseOrders with the static method in the class Collections replaceAll():
Collections.replaceAll(purchaseOrders, new Po("4500718933", "VWR SCIENTIFIC PRODUCTS - ECAT ONLY","24.81"), new Po("newPoNumber","newVendorName","newAmount"));

Remember Collection is an interface whose methods must be invoked via an instantiated object (e.g., purchaseOrders.add(...)) and Collections is a class with no constructor and static methods. It is never instantiated and is only used for its static methods (e.g., Collections.replaceAll(purchaseOders, ...))

Sorting ArrayList

If your Po class implements the interface Comparable, overriding the compareTo method, you can sort your ArrayList of purchase orders. The Return Value from compartTo is a 32-bit signed integer that indicates the relative order of the objects being compared. If it is less than zero, this instance is less than obj being passed. If it is zero, this instance is equal to obj being passed. If it is greater than zero, this instance is greater than obj.

compareTo()
compareTo

With compareTo implemented in your class, Po, the following Collections methods will work.

Collections.sort(purchaseOrders);
will sort the ArrayList of purchase orders in PO Number order.

Collections.reverse(purchaseOrders);
will sort the ArrayList of purchase orders in reverse PO Number order.

If you want to sort by different column(s) you will need static member classes within your Po class. In order to be comparators, these static member classes must implement the Comparator interface.

private static class CompareDate implements Comparator...

comparator class

In order to use this class as a comparator, it must be instantiated in a static method that returns it as a Comparator.

public static Comparator getComparator() {

return new Po.CompareDate(); ...

entire snippet of code:

method that returns comparator

Now it can be used in Collections.sort. Assuming that purchaseOrders is an ArrayList of Po, the following will sort your ArrayList in date order:

Collections.sort(purchaseOrders, Po.getComparator("date"));

All the code for the Object, Po is in Po.java.

All the code that builds and sorts the ArrayList purchaseOrders is in ListPo.java.

You can use po.txt as your test data.

Wrapper Classes

Integer, Double, Float, Long, Character.

Boxing & Unboxing Instance Methods or Constructors

To convert from int to Integer & visa versa (Boxing & Unboxing) use Constructor or Instance Methods in 1.4 & automatic in 1.5:

int i = 5;
Integer n = new Integer(i); // this is automatic in Java 1.5 (Integer n = i; // autoboxing at work)

Since the data mapping betw SAP & web uses the Wrapper Classes:
rfc.setMaxLimit(new Integer(500)); // 1.4 code
rfc.setMaxLimit(500); // 1.5 autoboxing code

To convert from Integer to int:

i = n.intValue(); // this is automatic in Java 1.5 (i = n;)

Integer -> intValue()
Double -> doubleValue()

Float -> floatValue()
Long -> longValue()
Character -> charValue()

Useful Static Methods in Wrapper Classes (both 1.4 & 1.5)

To convert from String to int or double, etc:

int i = Integer.parseInt("1234") ;
double d = Double.parseDouble("55.50");
etc.

int i = Integer.parseInt(theString.trim); // to get rid of leading & trailing blanks
double d = Double.parseDouble(theString.trim);
etc.

To convert from int, double, etc to String:

String s = Integer.toString(i);
String s = Double.toString(d);


Just in case you ever have to create an array...

ArrayTest

r1c1 r1c2 r1c3
r2c1 r2c2 r2c3
r3c1 r3c2 r3c3

produces the following output:
Print logically - all of inner for each outer (notice strings[j][i] - reverse of what would be expected)

r1c1
r1c2
r1c3
r2c1
r2c2
r2c3
r3c1
r3c2
r3c3

Reverse it - Print all of outer for each inner (strings[i][j] - what one would normally do)

r1c1
r2c1
r3c1
r1c2
r2c2
r3c2
r1c3
r2c3
r3c3

Called a subroutine and passed in the array as parameter

00
01
02
10
11
12
20
21
22


Static method Math.Random versus Random instance method

random example

Static method Math.random() follows

0.045471416183840874
0.687345516547068
0.059140720764281784
0.9797589349892067
0.32593880950514253
0.6635823923354919
0.01817624456934097
0.8261795722645922
0.7461529729565628
0.6965902006727052
0.6011560500890044

Random instance method follows rand.nextInt()

86539354
-426629965
-93648215
519404515
894486615
-925262895
-1157383229
1008889178
-1164321867
-34401143
-341676988

Random instance method follows rand.nextInt(100)

88
8
40
81
15
84
52
92
11
74
95