Thursday, October 18, 2007

Generics (A Compile-Time Protection)

All the generic code is strictly for the compiler. Through a process called "type erasure," the compiler does all of its verifications on your generic code and then strips the type information out of the class bytecode. None of your typing information exists at runtime.
In other words, even though you write
List myList = new ArrayList();


By the time the compiler is done with it, the JVM sees what it always saw before Java 5 and generics:
List myList = new ArrayList();

The compiler even inserts the casts for you—the casts you had to do to get things out of a pre-Java 5 collection. Think of generics as strictly a compile-time protection. The compiler uses generic type information (the in the angle brackets) to make sure that your code doesn't put the wrong things into a collection, and that you do not assign what you get from a collection to the wrong reference type. But NONE of this protection exists at runtime.

public class GenericTest
{
public static void main(String[] args)
{
List list1 = new ArrayList();
list1.add(7);
list1.add(16);
NonGeneric ng = new NonGeneric ();
ng.insert(list1);
System.out.println(list1);
}
}

class NonGeneric
{
void insert(List list)
{
list.add("hello");
}
}

Above code will compile and run without errors. Output will be
[7, 16, hello]

Improving Code Quality with PMD and Eclipse

PMD is a static code analyzer for Java. Developers use PMD to comply with coding standards and deliver quality code. Team leaders and Quality Assurance folks use it to change the nature of code reviews. PMD has the potential to transform a mechanical and syntax check oriented code review into a to dynamic peer-to-peer discussion.

What is PMD?
PMD works by scanning Java code and checks for violations in three major areas:

Compliance with coding standards such as:


Naming conventions - class, method, parameter and variable names
Class and method length
Existence and formatting of comments and JavaDocs
Coding antipatterns such as:

Empty try/catch/finally/switch blocks
Unused local variables, parameters and private methods
Empty if/while statements
Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
Classes with high Cyclomatic Complexity measurements
Cut and Paste Detector (CPD) - a tool that scans files and looks for suspect code replication. CPD can be parameterized by the minimum size of the code block.
In its current version, PMD comes packaged with 149 rules in 19 rulesets. Most of these rules can be parameterized at runtime by supplying properties or parameters. The standard package offers many well-thought rules. In addition users also have the ability to add their own rules for particular coding convention or quality metrics.

Here are some of the rules distributed with PMD:

EmptyFinalizer - If the finalize() method is empty, then it does not need to exist.
EmptyFinallyBlock - Avoid empty finally blocks - these can be deleted.
UnnecessaryReturn - Avoid unnecessary return statements
OnlyOneReturn - A method should have only one exit point, and that should be the last statement in the method.
CyclomaticComplexity - Complexity is determined by the number of decision points in a method plus one for the method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.
TooManyFields - Classes that have too many fields could be redesigned to have fewer fields, possibly through some nested object grouping of some of the information. For example, a class with city/state/zip fields could instead have one Address field.
LongVariable - Detects when a field, formal or local variable is declared with a long name.
NoPackage - Detects when a class or interface does not have a package definition

Compiling code in Eclipse

One of the best features of Eclipse is that it does not use the standard java compiler (javac.exe) which comes as part of the JDK. Eclipse instead comes bundled with

it's own compiler, which allows you to configure it in many interesting ways.For e.g. Some of the things you can do at compile time are as follows Report an error/warning for missing javadocs on public methods. Report an error/warning for malformed/incorrectly written javadocs.Report an error/warning for undocumented empty blocks.Report an error/warning for unused import statement.Report an error/warning for access to a null pointer.etc

All these settings can be configured by the settings under

Preferences -> Java -> Compiler.

Many of these settings are set to 'ignore' by default.

If set appropriately, Eclipse by itself can improve the quality of code which we write.

Wednesday, October 17, 2007

Don't Invoke Potentially Overridable Methods from a Constructor

You already know that you can't access any nonstatic things prior to your
superconstructor running, but keep in mind that even after an object's
superconstructor has completed, the object is still in an incomplete state
until after its constructor has finished. Polymorphism still works in a
constructor.

look at following example:-

public class B extends A

{

B()

{

}

public static void main(String[] arg)

{

new B().method();

}

public void method()

{

System.out.println("Class B method");

}

}

class A

{

A()

{

method();

}

public void method()

{

System.out.println("Class A method");

}

}

O/P will be

Class B method

Class B method

don't try this(called overridden method from constructor ) sort of stuff in
your code. If it's a final or private instance method, then you're safe
since you know it'll never be overridden.

Thread stop and suspend

Threads should not be stopped using stop or suspend. These methods are deprecated.

Instead, threads should use the following simple idiom to stop in a well behaved manner.

public final class SimpleThread implements Runnable {

public void run() {
boolean isDone = false;

while (!isStopRequested() && !isDone){
//perform the work
}
}

/**
* Request that this thread stop running.
*/
public synchronized void requestStop(){
fIsStopRequested = true;
}

// PRIVATE ////////

private boolean fIsStopRequested;

private synchronized boolean isStopRequested() {
return fIsStopRequested;
}
}

Wednesday, September 19, 2007

Shallow and Deep Copy

We generally clone an object using java.lang.Cloneable.clone(). This method makes a shallow copy and not a deep copy.

Difference between the two can be understood by using following example:


public class CloningExample implements Cloneable

{
private LinkedList names = new LinkedList();

public CloningExample()
{

names.add("abc");

names.add("xyz");
}


public Object deepClone() throws CloneNotSupportedException
{
CloningExample copy = (CloningExample)super.clone();

copy.names = (LinkedList)names.clone();

return copy;
}

public boolean equals(Object obj)
{
CloningExample tmp = (CloningExample)obj;

if (this.names == tmp.names)

return true;

else

return false;
}

public static void main(String[] args) throws CloneNotSupportedException
{
CloningExample ce1 = new CloningExample();

System.out.println("\nCloningExample[1] ----------------- " + ce1.names);

CloningExample ce2 = (CloningExample)ce1.clone();

System.out.println("\nCloningExample[2] ----------------- " + ce2.names);

System.out.println("\nCompare Shallow Copy --------------------\n" +

" ce1 == ce2 : " + (ce1 == ce2) + "\n" +

" ce1.equals(ce2) : " + ce1.equals(ce2));

CloningExample ce3 = (CloningExample)ce1.deepClone();

System.out.println("\nCompare Deep Copy --------------------\n" +

" ce1 == ce3 : " + (ce1 == ce3) + "\n" +

" ce1.equals(ce3) : " + ce1.equals(ce3));
}

}


Shallow Copy

CloningExample ce2 = (CloningExample)ce1.clone();

A clone ce2 of ce1 is created by simply calling the clone() method of Object. Our overridden equals() method tells us that the "names" are equivalent, but operator == tells that they aren't equal - that is, that are two distinct objects. This is what referred as a "Shallow Copy". Java simply copied the bits of our variables. This means that the "names" instance variable of both objects (ce1 and ce2) still holds the same information - that is, both objects have a reference to the same LinkedList.


Deep Copy

CloningExample ce3 = (CloningExample)ce1.deepClone();

The code above will perform a deep copy of the ce1 to ce3. The first part of the clone in the deep copy is the same as it was for the shallow copy. deepClone() method now

clones the LinkedList as well. Now, when CloningExample object is cloned, each CloningExample object (ce1 and ce3) will have its own LinkedList.

Monday, September 17, 2007

Pattern Matching and Regular Expression

Text processing frequently requires code to match text against patterns. That capability makes possible text searches, email header validation,custom text creation from generic text (e.g., "Dear Mr. Smith" instead of "Dear Customer"), and so on. Java supports pattern matching via its character and assorted string classes. Because that low-level support commonly leads to complex pattern-matching code, Java also offers regular expressions to help you write simpler code.

What are regular expressions?

A regular expression, also known as a regex or regexp, is a string whose pattern (template) describes a set of strings. The pattern determines what strings belong to the set, and consists of literal characters and metacharacters, characters that have special meaning instead of a literal meaning. The process of searching text to identify matches—strings that match a regex's pattern—is pattern matching.

See following link for more details

http://www.javaworld.com/javaworld/jw-02-2003/jw-0207-java101.html

Thursday, September 13, 2007

Serialization in Static and Transient Variable

If your object contains a Transient variable and if you write that object

into the file then on retreiving back the object from file you will get the

value corresponding to Transient variable as null

Also static variables are not serialized as they are not part of object state

Class Data Sharing

Overview
Class data sharing (CDS) is a new feature in J2SE 5.0 intended to reduce the startup time for Java programming language applications, in particular smaller applications, as well as reduce footprint (the amount of disk space required by an application). When the JRE is installed on 32-bit platforms using the Sun provided installer, the installer loads a set of classes from the system jar file into a private internal representation, and dumps that representation to a file, called a "shared archive". Class data sharing is not supported in Microsoft Windows 95/98/ME. If the Sun JRE installer is not being used, this can be done manually, as explained below. During subsequent JVM invocations, the shared archive is memory-mapped in, saving the cost of loading those classes and allowing much of the JVM's metadata for these classes to be shared among multiple JVM processes.

In J2SE 5.0, class data sharing is supported only with the Java HotSpot Client VM, and only with the serial garbage collector.

The primary motivation for including CDS in the 5.0 release is the decrease in startup time it provides. CDS produces better results for smaller applications because it eliminates a fixed cost: that of loading certain core classes. The smaller the application relative to the number of core classes it uses, the larger the saved fraction of startup time.

The footprint cost of new JVM instances has been reduced in two ways. First, a portion of the shared archive, currently between five and six megabytes, is mapped read-only and therefore shared among multiple JVM processes. Previously this data was replicated in each JVM instance. Second, since the shared archive contains class data in the form in which the Java Hotspot VM uses it, the memory which would otherwise be required to access the original class information in rt.jar is not needed. These savings allow more applications to be run concurrently on the same machine. On Microsoft Windows, the footprint of a process, as measured by various tools, may appear to increase, because a larger number of pages are being mapped in to the process' address space. This is offset by the reduction in the amount of memory (inside Microsoft Windows) which is needed to hold portions on rt.jar. Reducing footprint remains a high priority.

Regenerating the Shared Archive

Under some circumstances the system administrator may need to manually regenerate the shared archive. This is typically only necessary on Solaris if the J2SE packages were installed over the network to a machine of a different architecture than that performing the installation. Regardless, these regeneration instructions apply to all supported platforms.

The shared archive file is colocated with the shared library for the JVM. On Unix platforms, it is stored in jre/lib/[arch]/client/classes.jsa and on Microsoft Windows platforms in jre/bin/client/classes.jsa. If this file exists, it must be manually removed before regeneration.

To regenerate the archive, log in as the administrator; in networked situations, log on to a machine of the same architecture as the J2SE installation and ensure that you have permission to write to the installation directory. Then execute the command

java -Xshare:dump
Diagnostic information will be printed as the archive is generated.

Manually Controlling Class Data Sharing
The class data sharing feature is automatically enabled when conditions allow it to be used. The following command line options are present primarily for diagnostic and debugging purposes and may change or be removed in future releases.

-Xshare:off
Disable class data sharing.
-Xshare:on
Require class data sharing to be enabled. If it could not be enabled for various reasons, print an error message and exit.
-Xshare:auto
The default; enable class data sharing whenever possible.

Wednesday, September 12, 2007

Restriction to Use Generics

Enums, Exceptions and Anonymous classes are not applicable to use with Generics. The reason being is

1) An enum type and its enum values are static. Since type parameters cannot be used in any static
context, the parameterization of an enum type would be pointless

2) Generic exception or error types are disallowed because the exception handling
mechanism is a runtime mechanism and the Java virtual machine does not know anything
about Java generics

3) Anonymous classes do not have a name, but the name of a generic class is needed for declaring an
instantiation of the class and providing the type arguments

Dynamic Proxy Classes

Dynamic proxy classes : A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface



Example:-

public interface Foo {
Object bar(Object obj) throws BazException;
}

public class FooImpl implements Foo {
Object bar(Object obj) throws BazException {
// ...
}
}

public class DebugProxy implements java.lang.reflect.InvocationHandler {

private Object obj;

public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new DebugProxy(obj));
}

private DebugProxy(Object obj) {
this.obj = obj;
}

public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable
{
Object result;
try {
System.out.println("before method " + m.getName());
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " +
e.getMessage());
} finally {
System.out.println("after method " + m.getName());
}
return result;
}
}

Java Notes as Video

This is a good video that mentions some java practices. I tried to extract this as notes, but preferred to give the video, to better represent author thought.

http://video.google.com/videoplay?docid=9214177555401838409

Tuesday, September 11, 2007

Resource Release

The vast majority of resources used in Java programs are objects, and garbage collection does a fine job of cleaning them up. On the other hand, nonmemory resources like file handles and socket handles must be explicitly released by the program, using methods with names like close(), destroy(), shutdown(), or release(). If our application involves releasing multiple resources, such as in case of Database operations ( where we need to release ResultSet,Statement,Connection ), we usually follow the below approach.

public void enumerateFoo() throws SQLException {
Statement statement = null;
ResultSet resultSet = null;
Connection connection = getConnection();
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM Foo");
// Use resultSet
}
finally {
if (resultSet != null)
resultSet.close();
if (statement != null)
statement.close();
connection.close();
}

}
This may fail to release all resources if there is any problem while releasing "resultSet", "statement" objects.
To avoid this we can wrap each release operation in a try/catch block as shown below.
public void enumerateBar() throws SQLException {
Statement statement = null;
ResultSet resultSet = null;
Connection connection = getConnection();
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM Bar");
// Use resultSet
}
finally {
try {
if (resultSet != null)
resultSet.close();
}
finally {
try {
if (statement != null)
statement.close();
}
finally {
connection.close();
}
}
}
}

private Connection getConnection() {
return null;
}

Varargs Facility

Variable arity methods, sometimes referred to as varargs methods, accept an arbitrary set of arguments. Prior to JDK 5.0, if you wanted to pass an arbitrary set of arguments to a method, you needed to pass an array of objects. Furthermore, you couldn't use variable argument lists with methods such as the format method of the MessageFormat class or the new to JDK 5.0 printf method of PrintStream to add additional arguments for each formatting string present.



JDK 5.0 adds a varargs facility that's a lot more flexible. To explore the varargs facility, let's look at a JDK 5.0 version of one of the printf methods in the PrintStream class:

public PrintStream printf(String format, Object... args)

Essentially, the first argument is a string, with place holders filled in by the arguments that follow. The three dots in the second argument indicate that the final argument may be passed as an array or as a sequence of arguments.


The number of place holders in the formatting string determines how many arguments there need to be. For example, with the formatting string "Hello, %1s\nToday is %2$tB %2$te, %2$tY" you would provide two arguments: the first argument of type string, and the second of type date. Here's an example:

import java.util.*;

public class Today {
public static void main(String args[]) {
System.out.printf(
"Hello, %1s%nToday is %2$tB %2$te, %2$tY%n",
args[0], new Date());
}
}
Provided that you pass in an argument for the name, the results would be something like the following:

> java Today Ed
Hello, Ed
Today is October 18, 2005