Casting

     

The purpose of casting is to allow conversions from one type to another.

To get your mind around casting, it is helpful to think of the primitive types as being buckets of bits. Some buckets are bigger than others: long is a bucket of 64 bits, float is a bucket of 32 bits like int , and so forth.

Here is an example using primitives:

 

 short s = 16; //this is okay without cast, since int //is a bigger bucket (32 bits) than short (16 bits) int i = s; 

So we can do this, right?

 

 short s2 = s + 26; //Wrong!! Here's the output: net\javagarage\casts\Casting.java:21:       possible loss of precision found : int required: short                   short s2 = s + 26;                                ^ 1 error 

Where does Java say the error is? At the + operator. And what exactly is wrong with trying to add two short s together to make another short ? Nothing at all. Except, despite appearances , that's not what we're doing.

When you perform an operation like this on integral primitive types, the two operands are automatically promoted to int s, even though the result would fit inside a short . That's what always happens when you perform mathematical operations on integral types. To be promoted in this context means that they get to be a bigger sized bucket. And you can't fit an int -sized bucket into a short -sized bucket, can you?

Well, no you can't. In this case, we know that our resulting number (16 + 26 = 42) is plenty small enough to really be stored in a short . So we want to tell the compiler that we know it will be okay. Little E.T. will get home in the end. The cast in Java is the programmer's way of saying, "I know that you don't want me to do this, and you're usually smarter than I am, especially about Java, but I just need to do this right now, so you're going to have to trust me. If it blows up at runtime, I'll take responsibility."

The cast operator is ( ). In between the parens, you put the name of the type to which you want to cast.

So here's how we solve it:

 

 short s2 = (short) (s + 26); 

This gets us what we want: a short containing the result of 42. Notice that we have put parentheses around the addition operation. Why's that? Because if we didn't, the (short) operator would cast the variable s to a short (which it already is) and would then try to perform the addition, and what would happen? You'd be adding two short s together again, and the operation would promote the result to an int implicitly, and the compiler would blow up. Well, it wouldn't exactly "blow up," but it would become momentarily unhappy , and take it out on you in the form of console complaints.

When you cast, you leave yourself vulnerable to blowing up at runtime. Why's that? Because you are taking the reins. And you might not know as much about bits at runtime as the JVM. Not to rain on your parade (and we were just getting so excited about casting), but can you guess what happens here?

 

 //this is the most an int can hold: //2147483647 int j = Integer.MAX_VALUE; //knock it over the edge int result = j + 1; System.out.println(result); 

This is an error, right? No! It's perfectly legal. So what in the world does it print? An int can't, by definition, hold more than it can hold. It prints this:

 

 -2147483648 

Overflow is what happens when a result is too big for the type of variable that is meant to hold it (that is, the int 's bucket o' bits isn't big enough to hold +2147483648). What we've got here is an overflow.

If an integer overflows, only the least significant bits are stored. So exceeding your bucket's limit causes an overflow that results in a negative number ”in this case, the smallest possible value for an int . So you can guess what is printed here.

 

 j = Integer.MIN_VALUE; result = j - 1; 

Yep : 2147483647. It's like those revolving fireplace doors in those old Vincent Price movies. It just comes back around.

Java handles this situation differently for integer types than for floating point variables . When a double or a float overflows, the result is positive infinity. When a double or float underflows ”that is, when it is too small to be represented properly ”the result is 0.

Illegal operations, such as dividing by 0, result in NaN (Not a Number). Otherwise, floating point expressions will not raise exceptions; they will simply default to one of these predefined modes.

Note : You cannot cast a boolean primitive to any other primitive type in Java. It is "special." Shhhhh. This means you cannot convert a boolean to a 0 for false or a 1 for true as in some languages. A boolean 's values are the literals true and false , and those values aren't strings. They're boolean s.

Also note : If what you need is to perform some hard- core mathematical operations including unbounded arithmetic, you can use the five classes in the java.Math package (not java.lang.Math) BigInteger and BigDecimal. These guys perform more slowly than their counterparts in primitiveland do, and so they aren't used unless necessary.

And now, back to our previously scheduled topic. We were talking about casting.

This code is a compiler-error-making bit of code:

 

 int I = 37F; //No! 

The compiler will get mad, saying that you stiffed it. You told it you were going to provide an int , but instead you gave it a float .

The compiler doesn't like the following either ( sort of picky, this compiler ):

 

 float f = 69.99; 

Why in the world not? Remember how Java likes its integral types to be integers by default? It likes its floating point numbers to be double s by default. So here, we said that we'd give f a float , but instead, we gave her a double .

You have to make it explicit then, using the F following the float. This fixes it:

 

 float f = 69.99F; 

You can also write D following double s.

 

 double d = 87.65D;//ok jose double d = 122984.8604 //ok jose 

Note that casting from decimal to integral types can result in the parts following the decimal simply getting lopped off, as with a guillotine.

 

 double d = 1405.9876; int i = (int) d; //gives 1405 

Of course, hacking apart your floating point numbers in the manner of the chain saw may not prove aesthetically pleasing enough for you. In this case, you can try the java.lang.Math.round() method, which returns a passed float as an int .



Java Garage
Java Garage
ISBN: 0321246233
EAN: 2147483647
Year: 2006
Pages: 228
Authors: Eben Hewitt

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net