Previous | Next | Trail Map | How the Java Language Differs From C and C++ | How the Java Language Differs from C and C++


Java Strings are First-Class Objects

By convention, C and C++ strings are null-terminated array of characters; there is no real entity in C and C++ that is a string. Java strings are first-class objects.

Strings as objects provides several advantages to the programmer:

To illustrate why this is an important feature of the Java language, let's look at a small example. This C function copies the contents of str1 into str2.
int myStrCopy(char *str1, char *str2)
{
    for ( ; *str1 != '\0'; str1++, str2++)
        *str2 = *str1;
}

C Strings Behave Unpredictably

In the example shown above, the developer uses pointer arithmetic to step through both strings copying one into the other. While allowing programmers to inspect arbitrary memory locations through pointers is a powerful tool, this power can be the source of many errors. One fruitful source of errors is pointers that stray off the end of an array. The myStrCopy function above has such an error: the for loop in the function does not check the length of str2, and if str1 is longer than str2 the string copy writes right over the end of str2. Here's a program that tickles the bug.
main() {
    char *s = "HotJava is Cool!";
    char t[] = "Java is Cool!";

    printf("%s, %s\n", s, t);
    myStrCopy(s, t);
    printf("%s, %s\n", s, t);
}
On my machine, the program prints:
HotJava is Cool!, HotJava is Cool!%s, %s
myStrCopy writes over the end of str2 thereby corrupting whatever was stored in the memory after it. NOTE: %s, %s are the characters that happened to be stored in the memory location after str2 and will probably be different when you run the program on your machine.

Sure, the error in myStrCopy can be fixed easily. But errors like this are often difficult to find.

Java Strings are Predictable

Java strings are first-class objects deriving either from the String class or the StringBuffer class. This makes finding and fixing an entire class of common and frustrating programming errors such as the one illustrated above trivial.

Here's the program above (including the error) rewritten in the Java language.

class strcpy {
    public static void main(String args[]) {
        String s = "HotJava is Cool!";
        StringBuffer t = new StringBuffer("Java is Cool!");

        System.out.println(s + ", " + t);
        myStrCopy(s, t);
        System.out.println(s + ", " + t);
    }

    static void myStrCopy(String str1, StringBuffer str2) {
        int i, len = str1.length();

        for (i = 0; i < len; i++)
            str2.setCharAt(i, str1.charAt(i));
    }
}
Notice that this translation uses the String class, the StringBuffer class and the methods appropriate for obtaining specific characters instead of character arrays and pointers.

Like the C version, the Java language version of the myStrCopy method loops over the length of str1 and never checks the length of str2. Thus, when str1 is longer than str2, the method tries to obtain characters beyond the end of str2. However, when you run the Java language version, you'll see the following runtime error message.

Exception in thread "main" java.lang.StringIndexOutOfRangeException String index out of range: 13
    at java.lang.Exception.< init >(Exception.java)
    at java.lang.StringIndexOutOfRangeException.< init >(StringIndexOutOfRangeException.java)
    at java.lang.StringBuffer.setCharAt(StringBuffer.java)
    at strcpy.myStrCopy(strcpy.java:23)
    at strcpy.main(strcpy.java:15)
The primary difference between the Java language version of this program and the C version, is that the Java program will reliably and obviously crash, whereas the C program will do something obscure.


Previous | Next | Trail Map | How the Java Language Differs From C and C++ | How the Java Language Differs from C and C++