casting

††††††††††† integer casting

††††††††††† floating point casting

††††††††††† object casting and binding

 

integer casting

 

Some casting situations:

 

int x = 4096L;This is illegal. It requires an int downward cast like int x = (int) 4096L;

short sh = (short) 32800;This is over the 32,767 limit for short.It compiles but you get garbage with a negative leading bit.

byte b = 0;

b += 9;This works, as b receives implicit int casting.See widening rules

byte b = 0;

b = b + 9;†† The b = b + 9 is loss of precision as the 9 is an int, so it needs an explicit cast with complete enclosing parens.i.e. b = ( byte ) ( b+9 );

 

Narrowing primitive conversions simply lop off the appropriate number of lead bits.The sign can change.i.e.

 

int x = 129;

byte b = ( byte ) x;Here b becomes -127, not 129 as expected, because the bit in x which corresponds to b's sign happened to be on.

 

Upward conversions (like byte to char) always require explicit casts. i.e.

 

byte b = 0;

char c = '0';

Here bothb = c;andc = b;would require casts

 

You cannot convert a char (16 bit unsigned) to a short (also 16 bit) without explicit (short) casting. i.e.

 

short sh = 0;

char c = '0';

Here you needsh = ( short ) c;andc = ( char ) sh;to make the assignments.

 

When going from char (16 bit unsigned) to short (16 bit signed), the short takes on the charís lead bit as its sign.i.e.

 

char c = 0x8001;

short sh = ( short ) c;sh is then negative, -32767, because its lead bit was on.

 

floating point casting

 

The default for floating point is double.i.e.

 

float f = 2.0; requires explicit casting to float or f.††

float f = 2.0f;works.

float f = ( float ) 2.0;works.

 

object casting and binding

 

Objects retain their real identity (from the right hand side) after creation casting.i.e.

 

Object Obj = new Float( 1 );

Float F = new Float( 2 );

if ( Obj.equals( F ) ) uses the equals(...) method from the Float class, not Object's version.

 

Method references are resolved at run time, using the object's actual type (again taken from the right hand side). Variable references are resolved at compile time, using the object's declared type from the left.

The following example illustrates how you can change which runtime go( ) method is selected by casting object B.But such (run time) casting cannot change which (compile time) variable s is selected for printing.Boat's version of s is always used.The program prints:

 

Sub's go( )

Sub's go( )

Boat's s

public class RunTime {

††† public static void main(String[ ] args) {

††††††† Boat B = new Sub( );††††††††††† // B gets its runtime type here from the right, its declared type from the left

††††††† Sub S = new Sub( );

††††††† B.go( );†††††††††††††††††††††††††††††††††† // here B's runtime type via casting is used to find the method†††††††††††††††††††

††††††† S.go( );

††††††† B = S;†††††††††††††††††††††††††††††††††††† // this statement has no effect on method or variable selection

††††††† System.out.println( B.s );††† // here B's compile time declared type (Boat) is used to find the variable

††† }††

}

. . . .

class Boat {

††† String s = "Boat's s";

††† public void go( ) {

††††††† System.out.println( "Boat's go( )" );

††† }

}

class Sub extends Boat {

††† String s = "Sub's s";

††† public void go( ) {

††††††† System.out.println( "Sub's go( )" );

††† }

}

 

Object assignment casting tells the compiler to ignore it until run time.But even then the cast still canít go up the object hierarchy.No narrowing object casting is allowed to presumably "smaller" objects up the hierarchy.i.e.

 

Baseclass B = new Baseclass( );††

Subclass S = ( Subclass ) B;will compile but will give a runtime error because you donít know whatís extra in Subclass, which is presumably larger than Baseclass. So B canít be presumed to provide it.

SayingS = B;with no cast to Subclass, will not even compile.

 

null objects are not immune from the no downward casting rule. i.e.

 

Object o = null;

String s = null;

s = o;†††††††††††††††††††††† will not compile, as you canít assign upwards without a cast.

s = ( String ) o;††††††††††††† works here.

 

You cannot cast null to anything.