Converting Objects and Simple Variables

One of the most common tasks you'll need to accomplish in Java is to convert information from one form into another. There are several types of conversions you can do:

  • Converting an object into another object
  • Converting a simple variable into another type of variable
  • Using an object to create a simple variable
  • Using a simple variable to create an object

Simple variables are the basic data types you learned about during Hour 5, "Storing and Changing Information in a Program." These types include int, float, char, long, and double. When using a method or an expression in a program, you must use the right type of information that's expected by these methods and expressions. A method that expects a Calendar object must receive a Calendar object, for instance. If you used a method that takes a single integer argument and you sent it a floating-point number instead, an error would occur when you attempted to compile the program.

By the way

There is one area in which Java is less particular: strings. When a method such as System.out.println() requires a string argument, you can use the + operator to combine several different types of information in that argument. As long as one of the things being combined is a string, the combined argument will be converted into a string. This makes the following statements possible:

float sentence = 17.5F;
System.out.println("My sentence has been reduced to "
 + sentence + "years.");

Converting information into a new form in a program is called casting. Casting produces a new value that is a different type of variable or object than its source. You don't actually change the value of a variable or object when it is cast. Instead, a new variable or object is created in the format you need. The terms source and destination are useful when discussing the concept of casting. The source is some kind of information in its original form—whether it's a variable or an object. The destination is the converted version of the source in its new form.

Casting Simple Variables

With simple variables, casting occurs most commonly between numeric variables, such as integers and floating-point numbers. There's one type of variable that cannot be used in any casting: Boolean values. To cast information into a new format, you precede it with the new format surrounded by parenthesis marks. For example, if you wanted to cast something into a long variable, you would precede it with (long). For example, the following statements cast a float value into an int:

float source = 7.06F;
int destination = (int)source;

In a variable cast where the destination holds larger values than the source, the value is converted easily. An example is when a byte is cast into an int. A byte holds values from –128 to 127, while an int holds values from –2.1 million to 2.1 million. No matter what value the byte variable holds, there's plenty of room for it in a new int variable. You sometimes can use a variable in a different format without casting it at all. For example, char variables can be used as if they were int variables. Also, int variables can be used as if they were long variables, and anything can be used as a double.

By the way

A character can be used as an int variable because each character has a corresponding numeric code that represents its position in the character set. As an example, if the variable k has the value 67, the cast (char)k produces the character value 'C' because the numeric code associated with a capital C is 67, according to the ASCII character set. The ASCII character set is part of the Unicode character standard adopted by the Java language.

In most cases, because the destination provides more room than the source, the information is converted without changing its value. The main exceptions occur when an int or long variable is cast to a float, or a long is cast into a double. When you are converting information from a larger variable type into a smaller type, you must explicitly cast it, as in the following statements:

int xNum = 103;
byte val = (byte)xNum;

Casting is used to convert an integer value called xNum into a byte variable called val. This is an example where the destination variable holds a smaller range of values than the source variable. A byte holds integer values ranging from –128 to 127, and an int holds a much larger range of integer values: –2.14 billion to 2.14 billion. When the source variable in a casting operation has a value that isn't allowed in the destination variable, Java will change the value to make the cast fit successfully. This can produce unexpected results if you're not expecting the change.

Casting Objects

Objects can be cast into other objects as long as the source and destination are related by inheritance. One class must be a subclass of the other. Some objects do not require casting at all. An object can be used where any of its superclasses are expected. For example, because all objects in Java are subclasses of the Object class, you can use any object as an argument when an Object is expected. You also can use an object where one of its subclasses is expected. However, because subclasses usually contain more information than their superclasses, you might lose some of this information. If the object doesn't have a method that the subclass would contain, an error will result if that missing method is used in the program. To use an object in the place of one of its subclasses, you must cast it explicitly with statements such as the following:

JWindow win = new JWindow();
JFrame top = new (JFrame)win;

This casts a JWindow object called win into a JFrame object. You won't lose any information in the cast, but you gain all the methods and variables the subclass defines.

Converting Simple Variables to Objects and Back

One thing you can't do is cast an object to a simple variable or a simple variable to an object. These types of information are too different in Java for them to be substituted for each other. Instead, there are classes in the java.lang package for each of the simple variable types: Boolean, Byte, Character, Double, Float, Integer, Long, and Short. All of these classes are capitalized, which serves as a reminder that they are objects, rather than simple variable types. Using class methods defined in each of these classes, you can create an object using a variable's value as an argument. The following statement creates an Integer object with the value 5309:

Integer suffix = new Integer(5309);

After you have created an object like this, you can use it like any other object. When you want to use that value again as a simple variable, the class has methods for this also. For example, to get an int value from the preceding suffix object, the following statement can be used:

int newSuff = suffix.intValue();

This statement causes the newSuff variable to have the value 5309, expressed as an int value. One of the most commonplace casts from an object to a variable is when you have a string that should be used in a numeric way. This is done by using the parseInt() method of the Integer class, as in the following example:

String count = "25";
int myCount = Integer.parseInt(count);

This converts a string with the text 25 into an integer with the value 25. The next project you will create is an app that converts a string value in a command-line argument to a numeric value, a common technique when you're taking input from a user at the command line. Enter the text of Listing 10.1 in your word processor and save the file as

Listing 10.1. The Full Text of
 1: class NewRoot {
 2: public static void main(String[] arguments) {
 3: int number = 100;
 4: if (arguments.length > 0) {
 5: number = Integer.parseInt(arguments[0]);
 6: }
 7: System.out.println("The square root of "
 8: + number
 9: + " is "
10: + Math.sqrt(number) );
11: }
12: }

Compile the app using the javac tool included with the Java Development Kit or another compiler. When you run the program, specify an integer as a command-line argument, as in the following command:

java NewRoot 196

The program will display the number and its square root, as in this example:

The square root of 196 is 14.0

The NewRoot app is an expansion of an earlier tutorial from Hour 4, "Understanding How Java Programs Work." The Root program in that hour displayed the square root of the integer 225. That program would have been more useful if it took a number submitted by a user and displayed its square root. This requires conversion from a string to an integer. All command-line arguments are stored as elements of a String array, so you must be able to convert them to numbers before using them in mathematical expressions. To create an integer value based on the contents of a string, the Integer.parseInt() method is called with the string as the only argument, as in Line 5:

number = Integer.parseInt(arguments[0]);

Because arguments[0] holds the first command-line argument submitted when the app was run, the value of number will be an integer based on that string.

Autoboxing and Unboxing

Every one of the basic data types in Java has a corresponding object class: boolean (Boolean class), byte (Byte), char (Character), double (Double), float (Float), int (Integer), long (Long), and short (Short). For each of these pairs, the information has identical value. The only difference between them is the format the value takes. An integer value such as 413 could be represented by either an int or the Integer class. Java 2 version 5 includes support for autoboxing and unboxing, new language features that make it possible to use the basic data type and object forms of a value interchangeably. These features work behind the scenes, assuring that when you are expecting a data type, an object will be converted to the matching data type with the same value. This also is true in the other direction: a data type will be converted to an object as necessary.