JDK 1.5 has some very useful enhancements. Thanks to Josh Bloch of Sun Microsystems for helpful hints.
Early Access: there is an interactive version of this page here where you can post your code fragments to the community at large.
--------------------------------------------------------------------------------------
1.Autoboxing
Java's distinction between primitive types and their equivalent Object types was painful. Fortunately, with the advent of autoboxing, that will become a fading memory.
// automatically convert one type to another
Integer integer = 1;
System.out.println(integer);
// mix Integer and ints in the same expression
int i = integer + 3;
System.out.println(i);
Sample output:
1
4
--------------------------------------------------------------------------------------
2.Collections
The collections framework is greatly enhanced by generics, which allows collections to be typesafe.
LinkedList<String> stringList = new LinkedList<String>();
stringList.add("of");
stringList.add("course");
stringList.add("my");
stringList.add("horse");
Iterator<String> iterator = stringList.iterator();
for (String s : stringList)
System.out.print(s + " ");
Sample output:
of course my horse
--------------------------------------------------------------------------------------
3. Enhanced for loop
int array[] = {1, 2, 3, 4};
int sum = 0;
for (int e : array) // e is short for element; i would be confusing
sum += e;
System.out.println(sum);
Sample output:
10
--------------------------------------------------------------------------------------
4.Enums
Java programmers rejoice with the availability of enums.
enum Suit { clubs, diamonds, hearts, spades };
for (Suit suit : Suit.values())
System.out.println(suit);
Sample output:
clubs
diamonds
hearts
spades
Here is a more complex example.
enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
};
for (Iterator<Coin> i = Arrays.asList(Coin.values()).iterator();
i.hasNext(); ) {
Coin coin = i.next();
System.out.print(coin + " ");
}
Sample output:
penny nickel dime quarter
--------------------------------------------------------------------------------------
5. Formatted Output
Developers now have the option of using printf type functionality to generated formatted output. Most of the common C printf formatters are available.
System.out.printf("name count\n");
String user = "fflintstone";
int total = 123;
System.out.printf("%s is %d years old\n", user, total);
--------------------------------------------------------------------------------------
6. Importing Static Members
No longer is it necessary to write
Math.abs(x) Math.sqrt(x) Math.max(a, b)
We can now import once and write it like this:
import static java.lang.Math.*;
public class Import {
public static void main(String[] args) {
double x = 16.0, a = 2.2, b = 3.3;
System.out.println(abs(x));
System.out.println(sqrt(x));
System.out.println(max(a, b));
}
}
Sample output:
16.0
4.0
3.3
--------------------------------------------------------------------------------------
7. Improved Diagnostic Ability
This is one of Calvin Austin's code examples.
Generating Stack traces has been awkward if no console window has been available. Two new APIs, getStackTrace and Thread.getAllStackTraces provide this information programmatically.
StackTraceElement e[]=Thread.currentThread().getStackTrace();
for (int i=0; i <e.length; i++) {
System.out.println(e[i]);
}
System.out.println("\n"+Thread.getAllStackTraces());
Sample output:
java.lang.Thread.dumpThreads(Native Method)java.lang.Thread.getStackTrace(Thread.java:1333)Class2005.main(Class2005.java:5)
{Thread[Reference Handler,10,system]=[Ljava.lang.StackTraceElement;@130c19b,
Thread[main,5,main]=[Ljava.lang.StackTraceElement;@1f6a7b9,
Thread[Signal Dispatcher,10,system]=[Ljava.lang.StackTraceElement;@7d772e,
Thread[Finalizer,8,system]=[Ljava.lang.StackTraceElement;@11b86e7}
--------------------------------------------------------------------------------------
8. Metadata
This is one of Calvin Austin's code examples.
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @interface debug {
boolean devbuild() default false;
int counter();
}
public class MetaTest {
final boolean production=true;
@debug(devbuild=production,counter=1) public void testMethod() { }
public static void main(String[] args) {
MetaTest mt = new MetaTest();
try {
Annotation[] a = mt.getClass().getMethod("testMethod").getAnnotations();
for (int i=0; i<a.length ; i++) {
System.out.println("a["+i+"]="+a[i]+" ");
}
} catch(NoSuchMethodException e) {
System.out.println(e);
}
}
}
--------------------------------------------------------------------------------------
9. Monitoring and Manageability
This is one of Calvin Austin's code examples.
Monitoring and Manageability is a key component of RAS (Reliability, Availability, Serviceability) in the Java platform. The following code reports the detailed usage of the memory heaps in the Hotspot JVM. This feature isn't quite working yet, as you can see.
import java.lang.management.*;
import java.util.*;
import javax.management.*;
public class MemTest {
public static void main(String args[]) {
List pools =ManagementFactory.getMemoryPoolMBeans();
for(ListIterator i = pools.listIterator(); i.hasNext();) {
MemoryPoolMBean p = (MemoryPoolMBean) i.next();
System.out.println("Memory type="+p.getType()+" Memory usage="+p.getUsage());
}
}
}
Sample output:
Memory type=Non-heap memory Memory usage=initSize = 163840, used = 494144, committed = 524288, maxSize = 33554432Memory type=Heap memory Memory usage=initSize = 524288, used = 166440, committed = 524288, maxSize = -1Memory type=Heap memory Memory usage=initSize = 65536, used = 0, committed = 65536, maxSize = -1Memory type=Heap memory Memory usage=initSize = 65536, used = 0, committed = 65536, maxSize = 0Memory type=Heap memory Memory usage=initSize = 1441792, used = 0, committed = 1441792, maxSize = 61997056Memory type=Non-heap memory Memory usage=initSize = 8388608, used = 84360, committed = 8388608, maxSize = 67108864Memory type=Non-heap memory Memory usage=initSize = 8388608, used = 5844808, committed = 8388608, maxSize = 8388608Memory type=Non-heap memory Memory usage=initSize = 12582912, used = 6010560, committed = 12582912, maxSize = 12582912## An unexpected error has been detected by HotSpot Virtual Machine:## SIGSEGV (0xb) at pc=0x42073770, pid=24776, tid=1073993792## Java VM: Java HotSpot(TM) Client VM (1.5.0-beta-b31 mixed mode)# Problematic frame:# C [libc.so.6+0x73770] __libc_free+0x70## An error report file with more information is saved as /tmp/hs_err_pid24776.log## If you would like to submit a bug report, please visit:# http://java.sun.com/webapps/bugreport/crash.jsp#
--------------------------------------------------------------------------------------
10. Variable Arguments
This is just using ellipses as syntactic sugar for arrays.
public class Test {
// main() looks different, doesn't it?
// try changing the runtime arguments above and rerun
public static void main(String... args) {
System.out.println(args.length + " arguments");
}
}
Sample output:
3 arguments
Challenge: Here is a program that reads the name of a class from the command line, followed by a method name. It instantiates an object of the specified type, and invokes the method. For example, if fed a command line like java.util.Date toString, this program will print the current date and time. Of course, this class only works with methods that don't require arguments. The challenge is to use ellipses to specify the variable arguments to invoke.
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
try {
Class klass = Class.forName(args[0]);
Object instance = klass.newInstance();
Method method = klass.getDeclaredMethod(args[1], new Class[] {} );
Object object = method.invoke(instance, new Object[] {} );
System.out.println(object);
} catch (java.lang.InstantiationException ie) {
ie.printStackTrace();
} catch (java.lang.IllegalAccessException iae) {
iae.printStackTrace();
} catch (java.lang.reflect.InvocationTargetException ite) {
ite.printStackTrace();
} catch (NoSuchMethodException nsme) {
nsme.printStackTrace();
} catch (Exception e) { // in case method.invoke() throws
e.printStackTrace();
}
}
}
--------------------------------------------------------------------------------------
11. Word Frequency Counter
This is Josh Bloch's new and improved word frequency counter.
import java.text.*;
import java.util.*;
public class Freq {
public static void main(String[] args) {
Map<String, Integer> m = new TreeMap<String, Integer>();
for (String word : args) {
Integer freq = m.get(word);
m.put(word, (freq == null ? 1 : freq + 1));
}
System.out.println(m);
}
}
--------------------------------------------------------------------------------------
12. Grep
This is one of Sun's NIO examples. This program has a bug: instead of working from a directory name or accepting wildcards, the only way it works is to specify the exact filename that you are looking for... which defeats the purpose. Perhaps you'd like to figure out the fix?
We have placed files in the JDK 1.5 shared sandbox called /usr/share/fileXX.data, where XX runs from 1 to 10. These files have privileges that allow them to be read by users, so this example will be able to generate viewable results. If you attempt read a file for which you do not have privilege, a java.io.FileNotFoundException error will result.
/* Search a list of files for lines that match a given regular-expression
* pattern. Demonstrates NIO mapped byte buffers, charsets, and regular
* expressions. */
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.regex.*;
public class Grep {
// Charset and decoder for ISO-8859-15
private static Charset charset = Charset.forName("ISO-8859-15");
private static CharsetDecoder decoder = charset.newDecoder();
// Pattern used to parse lines
private static Pattern linePattern
= Pattern.compile(".*\r?\n");
// The input pattern that we're looking for
private static Pattern pattern;
// Compile the pattern from the command line
//
private static void compile(String pat) {
try {
pattern = Pattern.compile(pat);
} catch (PatternSyntaxException x) {
System.err.println(x.getMessage());
System.exit(1);
}
}
// Use the linePattern to break the given CharBuffer into lines, applying
// the input pattern to each line to see if we have a match
//
private static void grep(File f, CharBuffer cb) {
Matcher lm = linePattern.matcher(cb); // Line matcher
Matcher pm = null; // Pattern matcher
int lines = 0;
while (lm.find()) {
lines++;
CharSequence cs = lm.group(); // The current line
if (pm == null)
pm = pattern.matcher(cs);
else
pm.reset(cs);
if (pm.find())
System.out.print(f + ":" + lines + ":" + cs);
if (lm.end() == cb.limit())
break;
}
}
// Search for occurrences of the input pattern in the given file
//
private static void grep(File f) throws IOException {
// Open the file and then get a channel from the stream
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();
// Get the file's size and then map it into memory
int sz = (int)fc.size();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
// Decode the file into a char buffer
CharBuffer cb = decoder.decode(bb);
// Perform the search
grep(f, cb);
// Close the channel and the stream
fc.close();
}
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Usage: java Grep pattern file...");
return;
}
compile(args[0]);
for (int i = 1; i < args.length; i++) {
File f = new File(args[i]);
try {
grep(f);
} catch (IOException x) {
System.err.println(f + ": " + x);
}
}
}
}
Sample output
This is file #1This is file #2
This is file #3
This is file #4
This is file #5
This is file #6
This is file #7
This is file #8
This is file #9
This is file #10