October 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Primitives and Object Wrappers

  • June 6, 2006
  • By Matt Weisfeld
  • Send Email »
  • More Articles »

You would get the same behavior by simply reusing the original string, as seen in Listing 7. Even in this case, there actually are two strings being created. Rather than transform the original string, this code creates a second string in memory, despite the fact that this is not apparent by examining the code. Once the second string is created, the reference s1 is literally re-pointed to the new string in memory. At this point, the memory for the original string is essentially an orphan. Once this happens, the garbage collector then reclaims this orphaned memory.

public class Primitives {

   public static void main(String[] args) {

      String s1 = "abc";

      s1 = s1.toUpperCase();

      System.out.println("s1 = " + s1);

   }
}

Listing 7

In the same vein, strings are not processed at the character level, but with methods provided by the String class. One of the most common behaviors is that of comparing strings. The example in Listing 8 shows one of the ways to use the equals() method of the String class.

public class Primitives {

   public static void main(String[] args) {

      String s1 = "abc";
      String s2 = "abd";

      if (s1.equals(s2)) {
         System.out.println("strings are the same");
      }else {
         System.out.println("strings are not the same");
      }

   }
}

Listing 8

The output in Figure 6 shows what happens when you execute this code. If the two strings are equal, the binary value of true is returned. In this example, the strings are not identical, so the binary value of false is returned.

Figure 6

Primitive Wrappers

As was mentioned earlier, the Java primitives are not objects. Although Java is considered an object-oriented language, obviously not everything is an object, as is the case in some other object-oriented languages. However, all the primitive types have a corresponding wrapper class. Many of these classes are spelled the same; however, the first character in the name of the wrapper class is always capitalized. The key is to realize that these wrappers are all classes.

There are several reasons why you would want to use a wrapper class; however, the most important may be that there are some situations where you must treat everything as an object. Because an int, for example, is not an object, the next best thing is to wrap it inside an object. The Integer class is used as this wrapper.

When I was first learning Java, use of the Integer class helped me understand the concept of a wrapper. I encountered this the first time I wanted to convert an argument from the command line. In C/C++, I could process the character string in the argument list directly by using the atoi() function.

void main( int argc, char *argv[] ) {

   cout<<"Convert to an integer: "<<atoi(argv[0]);

}

In Java, an approach like this won't work. Because everything, in effect, is treated like an object, you can't process a primitive in this way. To convert a string to an int, you must first create an Integer object wrapper and then use the behaviors of this class to do the conversion as shown in Listing 9.

public class Primitives {

   public static void main(String[] args) {

      Integer i = new Integer(0);

      int val = Integer.valueOf(args[0]);

      System.out.println("val = " + val);

   }
}

Listing 9

The output from this code is presented in Figure 7. Notice that the string "100" is converted to an int 100 and then added to the constant value 2.

Figure 7

In reality, if all you need is to convert the number, and not create a whole new object, you can use the class in static fashion. In short, you can statically use the functionality of the Integer class by specifying the Integer class instead of an actual object. Listing 10 shows how this is accomplished.

public class Primitives {

   public static void main(String[] args) {

      int val = Integer.valueOf("100");

      System.out.println("val = " + (val + 2) );

   }
}

Listing 10

The Java specification at http://java.sun.com/j2se/1.3/docs/api/java/lang/Integer.html shows that the valueOf() method is declared as static; this allows a programmer to access the method at the class level. This is true for many methods of the wrapper classes.

static Integer valueOf(String s)
          Returns a new Integer object initialized to the value of the specified String.

When you execute the code in Listing 10, you must provide an argument, as shown in Figure 8.

Figure 8

JDK 1.5 Enhancements

In the JDK 1.5 release, the compiler "recognizes the relationship between primitive variables and objects of their corresponding wrapper type". [1] By using techniques called autoboxing and unboxing, you can deal with wrappers more intuitively.

Autoboxing

Rather than having to explicitly create an Integer wrapper as in earlier versions of the SDK,

Integer wrapper = new Integer(0);

you now can let the compiler deal it, as you can see in Listing 10.

public class Primitives {

   public static void main(String[] args) {

      Integer wrapper = 33;

      System.out.println("wrapper = " + wrapper );

   }
}

Listing 10

Unboxing

Unboxing is the complimentary action to autoboxing. Again, rather than explicitly declaring the wrapper,

Integer wrapper = new Integer(0);

you can let the compiler deal with the details. In Listing 11, you create an Integer wrapper and then directly set an int to the wrapper itself.

public class Primitives {

   public static void main(String[] args) {

      Integer wrapper = 33;

      int i = wrapper;

      System.out.println("i = " + i );

   }
}

Listing 11

Although autoboxing and unboxing are very convenient, be aware that in both cases, the compiler actually will generate similar bytecodes to the pre JDK 1.5 syntax.

Conclusion

In this article, you explored the various relationships among Java primitives, objects, and object wrappers. These are important concepts because the use of object wrappers is a very powerful technique and used in many applications. One of the more common uses of object wrappers is to wrap operating system functionality such as interfaces with hardware. The use of Sockets that you saw in an earlier article is a good example of how specific functionality is wrapped, and thus transparent, to the Java programmer.

The topic of wrappers also is a very good way to understand what object concepts are all about. Because these wrappers contain attributes and behaviors, they a very good example of how objects are packaged.

References


[1] Just Java 2, 6th Edition. Peter van der Linden. Page 55.

About the Author

Matt Weisfeld is a faculty member at Cuyahoga Community College (Tri-C) in Cleveland, Ohio. Matt is a member of the Information Technology department, teaching programming languages such as C++, Java, and C# .NET as well as various web technologies. Prior to joining Tri-C, Matt spent 20 years in the information technology industry gaining experience in software development, project management, business development, corporate training, and part-time teaching. Matt holds an MS in computer science and an MBA in project management. Besides The Object-Oriented Thought Process
, which is now in it's second edition, Matt has published two other computer books, and more than a dozen articles in magazines and journals such as Dr. Dobb's Journal, The C/C++ Users Journal, Software Development Magazine, Java Report, and the international journal Project Management. Matt has presented at conferences throughout the United States and Canada.





Page 3 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel