Home arrow Java arrow Java in Review

Java in Review

Tired of hearing about the gory syntax details of Java? Keep reading for a more conceptual view of the language, focusing on important issues that deserve more attention than they usually receive. Even an advanced programmer will find useful information in this article. It was excerpted from chapter one of Hardcore Java, edited by Robert Simmons Jr. (O'Reilly, 2004; ISBN: 0596005687).

Author Info:
By: O'Reilly Media
Rating: 4 stars4 stars4 stars4 stars4 stars / 12
June 16, 2005
  1. · Java in Review
  2. · Syntax Issues
  3. · Collection iteration with for
  4. · Labels
  5. · Assertions versus exceptions
  6. · Assertions and deployment
  7. · Initialization
  8. · Access Issues
  9. · Common Mistakes

print this article

Java in Review
(Page 1 of 9 )

I can hear the groans from here—a review on Java? Don’t worry, I won’t bore you with all of the gory syntax details or concepts of the Java language that you can easily pick up in other books. Instead, I will present a conceptual review that focuses on some various important issues that are often overlooked or underemphasized. The study of these issues will not only give you a better understanding of the Java language, but prepare you for what’s covered in the rest of the book. You should think of this chapter as a roving spotlight, highlighting various issues of Java that are worthy of mention; even the intermediate and advanced programmer will benefit from the study of these issues.

Core Concepts

To understand the advanced concepts of the Java language, there are a few core concepts that you must have firmly in mind. Without these concepts, much of this book will not make a lot of sense. The concepts of pointers in Java, its class hierarchy, and RTTI (runtime type identification) are three of the most important on this list.

Constant Problems with Pointers

Java and C++ use a very analogous syntax to symbolize their instructions to the computer’s CPU. In fact, there are probably more similarities between these languages than the two entrenched camps of supporters would like to admit. One difference between Java and C++ that is often mentioned, though, is that Java does not use pointers.

Pointers in C++ were a constant source of problems and were determined to be the programming equivalent of evil incarnate. There was, and is to this day, a large group of applications in C++ that suffer from the effects of this particular wrong. Therefore, Sun decided to leave them out of Java—at least that’s the theory.

In reality, Java uses what C++ calls references. In fact, other than primitives, all variables in Java are references. References and pointers are very similar; both contain the memory location of a particular object. Pointers, however, allow you to do arithmetic whereas references do not. The fact that Java uses so many references introduces some difficulties that novice and proficient Java developers often get burned by. The code shown in Example 1-1 demonstrates one of these difficulties.

Example 1-1. Collections are passed as references

  package oreilly.hcj.review;
  public class PointersAndReferences {
public static void someMethod(Vector source) {
Vector target = source;

Here, you simply copy the passed-in source vector and add a new element to the copy (named target); at least that is how it appears. Actually, something quite different happens. When you set target equal to source in the code, you copy a reference to the target vector, and not the contents of the vector itself. Since both variables now point to the same vector, this function actually adds an element to the source vector that was passed into the method; this was almost certainly not the desired effect! We will discuss how to prevent this problem in Chapter 2.

Since you can change the contents of an incoming collection, Java actually does have pointers—that is, Java references embody the same computer science principles that pointers do. So, when someone tells you that Java doesn’t have pointers, you can correct them by saying, “Java has pointers, it just doesn’t have pointer arithmetic.”

Also, Java’s use of references isn’t a bad thing. In fact, the references are actually necessary to the Java language. Without them, you would have to pass everything by value. This would entail copying every single object each time an object was passed to a method. If the object were a String, this copying probably wouldn’t be a big deal. However, if the object is a large array or set, the copy could take a long time. Therefore, passing everything by value would make Java code run extremely slowly. Furthermore, some objects simply don’t make sense to copy at all. If you have a GUI panel and wish to pass the GUI panel to another component that needs to refer to it, you certainly don’t want two copies of the panel floating around in memory. Instead, you want to send a reference to the existing panel. All of these issues point out the need for references in Java.

Everything Is a Class and Object Is God

In Java, all constructed types are regarded as objects. In fact, the only items in Java that are not objects are the primitive types, such as int and boolean; and even these primitive types can be treated as objects under some circumstances, such as when you use reflection.

I would expect that most Java programmers would find this trivial since they already know that every nonprimitive in Java is an object. The point that I am really trying to make, though, is that every constructed type in Java descends from the class java. lang.Object. Even if you don’t declare a class as extending java.lang.Object, you still get this behavior. Example 1-2 shows a class that explicitly extends java.lang.Object, while Example 1-3 is a class that has no explicit extension.

Example 1-2. Explicitly extending java.lang.Object

  public class SomeClass extends Object {

Example 1-3. Implicitly extending java.lang.Object

  public class SomeClass {

In Example 1-2, SomeClass makes its object hierarchy clear; its superclass is Object.

Example 1-3, while visibly different, is actually equivalent to Example 1-2. The Java compiler will automatically assign the superclass of Object to this version of SomeClass.

In fact, even a class that implements interfaces instead of extending another class extends java.lang.Object. As a result, these two declarations are identical:

  public class SomeClass extends Object implements Serializable {
public class SomeClass implements Serializable {

So, unlike C++, you cannot create a class that does not have a superclass. Object is the superclass to all classes in the entire language. In the example code for this book, you will find the class oreilly.hcj.review.ObjectIsGod, which demonstrates this concept:

  > ant –Dexample=oreilly.hcj.review.ObjectIsGod run_example
       [java] class reilly.hcj.review.ObjectIsGod$SomeClass --|> class
       [java] class oreilly.hcj.review. ObjectIsGod$SomeOtherClass --|> class

There are three main reasons why java.lang.Objectis always at the top of the inheritance tree:

  • For Java to know the type of objects it must load, and to enforce type safety, it has to have some base type with which it can refer to all objects.

  • Java currently lacks the concept of the parameterized type(also known as atemplate). This means that all the objects that are be stored in collection classes ultimately have to descend from one class.

  • The fact that all objects have java.lang.Object as a superclass gives you supreme power when it comes to using reflection to turbocharge your code. Without this sort of inheritance, many techniques in reflection would be impractical. (We will discuss reflection in detail in Chapter 9.)


Runtime type identification, or RTTI, is an extremely powerful tool. With RTTI, objects become very friendly and readily tell you what they are, how they are used, and more. In Java, RTTI is built right into the core of the virtual machine. You’ve almost certainly used RTTI, even if you don’t realize it; it’s all over the place. For example, consider that every object in Java can tell you what type it is through the getClass( ) method. Whenever you invoke getClass( ), you use RTTI. Example 1-4 shows the getclass( ) method in action.

Example 1-4. Demonstration of basic RTTI usage

  package oreilly.hcj.review;
  public class RTTIDemo {
public final static void basicRTTIDemo (){
      Float y = new Float(15.0);
      String name = "Fred";

This method will, quite politely, print the following:

  >ant –Dexample=oreilly.hcj.review.RTTIDemo run_example
      [java] class java.lang.Float
      [java] class java.lang.String

Since the getClass() method is a method defined by the class java.lang.Object, it is guaranteed to be there for all objects.

Java also uses RTTI to protect a programmer from her own errors, as Example 1-5 demonstrates.

Example 1-5. RTTI enforces type safety

  package oreilly.hcj.review;
public class RTTIDemo {
    public static class A {
    public static class B extends A {
public static class C {
public final static void castingWithRTTI () {
      A a = null;
      A a1 = new A();
      B b = new B();
      C c = new C();
a = (A)b; // no problem
      b = (B)a; // still no problem, casting back to what it was created as.
      a = a1; // Same type so no problem
      Object d = (Object)c; // no problem because of implicit inheritance
      c = (C)d; // casting back
      b = (A)a1; // compiler error: a1 is not a B.
      b = (B)c; // compiler error: c is not a B.

This code shows how to create an object of a subclass, cast it to its base class, and then cast it back to the subclass. RTTI works in the background to ensure that your casting is always legal; in other words, an object can safely be cast only to its own type, or to a type that it is inherited from. In the sample code for the book, Example 1-5 is replicated with the bad casts commented out. If you uncomment these lines, you will see that the program won’t even compile, and you will get errors such as those shown here:

  >ant -Dexample=oreilly/hcj/review/RTTIDemo.java compile_example
      [javac] Compiling 1 source file to C:\dev\hcj\bin  
      {javac]  C:\dev\hcj\src\oreilly\hcj\review\RTTIDemo.java:54: incompatible types
      [javac] found : oreilly.hcj.review.RTTIDemo.A
      [javac] required: oreilly.hcj.review.RTTIDemo.B 
      [javac] b = (A)a1; // compiler error: a1 is not a B.
      [javac]     ^
      [javac] C:\dev\hcj\src\oreilly\hcj\review\RTTIDemo.java:55: inconvertible types
      [javac] found : oreilly.hcj.review.RTTIDemo.C
      [javac] required: oreilly.hcj.review.RTTIDemo.B  
      [javac] b = (B)c; // compiler error: c is not a B. 
      [javac]        ^
      [javac] 2 errors

RTTI is useful for preventing common errors in programming. It also has many other uses; we will get to the juicy details of exploiting RTTI in Chapters 7 and 8.

blog comments powered by Disqus

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


© 2003-2019 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials