Home
SOA
Spring-Hibernate
GOF Design Patterns
Java BP
Java Tutorial
Java Traps
Datawarehouse
C++ Tutorial
Unix Commands
Interview QnA
About MDC

Java Common Mistakes

  • Accessing non-static member variables from static methods (such as main)
    Many programmers, particularly when first introduced to Java, have problems with accessing member variables from their main method. The method signature for main is marked static - meaning that we don't need to create an instance of the class to invoke the main method. For example, a Java Virtual Machine (JVM) could call the class MyApplication like this :-

    MyApplication.main ( command_line_args );

    This means, however, that there isn't an instance of MyApplication - it doesn't have any member variables to access! Take for example the following application, which will generate a compiler error message.

    public class StaticDemo
    {
    public String my_member_variable = "somedata";
    public static void main (String args[])
    {
    // Access a non-static member from static method
    System.out.println ("This generates a compiler error" +
    my_member_variable );
    }
    }
    If you want to access its member variables from a non-static method (like main), you must create an instance of the object. Here's a simple example of how to correctly write code to access non-static member variables, by first creating an instance of the object.

    public class NonStaticDemo
    {
    public String my_member_variable = "somedata";

    public static void main (String args[])
    {
    NonStaticDemo demo = new NonStaticDemo();

    // Access member variable of demo
    System.out.println ("This WON'T generate an error" +
    demo.my_member_variable );
    }
    }
     
  • Confusion over passing by value, and passing by reference
    This can be a frustrating problem to diagnose, because when you look at the code, you might be sure that its passing by reference, but find that its actually being passed by value. Java uses both, so you need to understand when you're passing by value, and when you're passing by reference.

    When you pass a primitive data type, such as a char, int, float, or double, to a function then you are passing by value. That means that a copy of the data type is duplicated, and passed to the function. If the function chooses to modify that value, it will be modifying the copy only. Once the function finishes, and control is returned to the returning function, the "real" variable will be untouched, and no changes will have been saved. If you need to modify a primitive data type, make it a return value for a function, or wrap it inside an object.

    When you pass a Java object, such as an array, a vector, or a string, to a function then you are passing by reference. Yes - a String is actually an object, not a primitive data type. So that means that if you pass an object to a function, you are passing a reference to it, not a duplicate. Any changes you make to the object's member variables will be permanent - which can be either good or bad, depending on whether this was what you intended.

    On a side note, since String contains no methods to modify its contents, you might as well be passing by value.

     
  • Null pointers are one of the most common errors that Java programmers make. Compilers can't check this one for you - it will only surface at runtime, and if you don't discover it, your users certainly will.

    When an attempt to access an object is made, and the reference to that object is null, a NullPointerException will be thrown. The cause of null pointers can be varied, but generally it means that either you haven't initialized an object, or you haven't checked the return value of a function.

    Many functions return null to indicate an error condition - but unless you check your return values, you'll never know what's happening. Since the cause is an error condition, normal testing may not pick it up - which means that your users will end up discovering the problem for you. If the API function indicates that null may be returned, be sure to check this before using the object reference!

    Another cause is where your initialization has been sloppy, or where it is conditional. For example, examine the following code, and see if you can spot the problem.

    public static void main(String args[])
    {
    // Accept up to 3 parameters
    String[] list = new String[3];

    int index = 0;

    while ( (index < args.length) && ( index < 3 ) )
    {
    list[index++] = args[index];
    }

    // Check all the parameters
    for (int i = 0; i < list.length; i++)
    {
    if (list[i].equals "-help")
    {
    // .........
    }
    else
    if (list[i].equals "-cp")
    {
    // .........
    }
    // else .....
    }
    }
    This code (while a contrived example), shows a common mistake. Under some circumstances, where the user enters three or more parameters, the code will run fine. If no parameters are entered, you'll get a NullPointerException at runtime. Sometimes your variables (the array of strings) will be initialized, and other times they won't. One easy solution is to check BEFORE you attempt to access a variable in an array that it is not equal to null.

     
  • Treating Strings as In/Out Parameters
    Java's string class, java.lang.String, provides a good encapsulation of string data. However, Java strings are (1) immutable, and (2) objects. Therefore, they cannot be treated as simple character buffers; they must be treated as immutable opaque objects. Sometimes, a student will attempt to treat a String parameter to a method as if it were a character array passed by reference (as in a C char array, or a C++ STL string object). This is a fairly subtle mistake, but one which usually passes the compiler.
    Mistake Example
    public static void main(String args[]) {
    String test1 = "Today is ";
    appendTodaysDate(test1);
    System.out.println(test1);
    }
    public void appendTodaysDate(String line) {
    line = line + (new Date()).toString();
    }



    In the example above, the student is expecting to change the value of main's local variable test1 by assigning a value to the parameter line in the appendTodaysDate method. Of course, this won't work; the local value of line will change, but the string test1 will be unaffected.

    This mistake can come up if the student has not yet accepted the fact that (1) Java objects are always passed by handle, and (2) Java strings are immutable. As the instructor, you have to explain Java parameter passing, and emphasize that String objects never change their value, but instead all String operations merely create new String objects.

    For the particular problem shown above, the fix is either to return a string value from the method, or to pass a StringBuffer object instead of a String object.

    Corrected Example 1
    public static void main(String args[]) {
    String test1 = "Today is ";
    test1 = appendTodaysDate(test1);
    System.out.println(test1);
    }
    public String appendTodaysDate(String line) {
    return (line + (new Date()).toString());
    }


    Corrected Example 2
    public static void main(String args[]) {
    StringBuffer test1 = new StringBuffer("Today is ");
    appendTodaysDate(test1);
    System.out.println(test1.toString());
    }
    public void appendTodaysDate(StringBuffer line) {
    line.append((new Date()).toString());
    }
     
  • Using double data type in financial calculations results in lost of precision. For more details refer to a detailed discussion here.
  • In Java, a single equal sign ( = ) is an entirely different operator than a double equal sign ( == ). In most cases, use the double equal sign when creating a loop or conditional statement and use the single equal sign everywhere else. For example:
    To compare a and b for equality, use a==b; (note the double equal sign).
    Where b has the same value as a, use a=b; (note the single equal sign).