Home | Blog | Java | Jokes | Poems | Musings | Site Map | Kudos | Downloads | Useful Sites | Interesting | System Setup | Contact

Home Page

AKGBackup - The backup program

            

 

Section 5 : Operators and Assignments


Determine the result of applying any operator, including assignment operators, instanceof, and casts to operands of any type, class, scope, or accessibility, or any combination of these.


 

 

Converting and Casting 

 

 

Automatic, non-explicit (done by compiler or Java) type changing is known as conversion. On the other hand explicitly changing the type of a value is called casting. Both are governed by certain rules. 

 

Primitives and conversion 

 

All conversion of primitive data type takes place at compile time. This is because all the information, needed to determine whether or not conversion is legal, is available at compile time.

 

Assignment

 

Assignment conversion happens when you assign a value to a variable of a different type from the original value. The general rules are:

 

  • A boolean may not be converted to any other type.

  • A non boolean may be converted to another non boolean type, provided the conversion is a widening conversion.

  • A non boolean may not be converted to another non boolean type, if the conversion is narrowing.

 

You cannot convert a byte to a char or a char to a short, even though it seems reasonable to do so.

 

Method call: 

 

Another kind of conversion is method-call-conversion. This happens when you pass a value of one type as an argument to a method that expects a different type. Here too, widening conversions are permitted, not narrowing. 

 

Arithmetic promotion:

 

These too, are widening conversions.

 

Unary operators:

 

  • If the operand is a byte, a short or a char, it is converted to an int.

  • If the operand is of any other type, it is not converted.

 

Binary operators:

 

  • If one of the operands is double, the other operand is converted to a double.

  • Else if one of the operand is a float, the other operand is converted to a float.

  • Else if one of the operand is long, the other operand is converted to a long.

  • Else both operands are converted to int.

 

Primitives and casting 

 

Casting means explicitly telling Java to make a conversion. A casting may widen or narrow its argument. But casting is required when you want to perform a narrowing conversion.

Narrowing runs the risk of losing information; the cast tells the compiler that you accept the risk. During casting the lower order bits are preserved and higher order bits are discarded depending on the operands. The rules are:

 

  • Any non  boolean can be cast to any non boolean.

  • A boolean cannot be cast to a non boolean and vice versa.

 

Note that while casting is ordinarily used when narrowing, it is perfectly legal to cast when widening. The cast is unnecessary, but provides clarity.

 

*** if you cast a negative number to a char, ? is printed in S.o.p(); also any number less than 0 and greater than 255 gives the same output.

 

Object reference conversion 

 

Reference conversion, like primitive conversion, takes place at compile time, because the compiler has all the information it needs to determine whether the conversion is legal.

 

Object reference assignment conversion: 

 

There are generally three kinds of object reference type:

  • A class type

  • An interface type

  • An array type

Assignment conversion looks like this:

 

OldType x = new OldType();

NewType y = x; // reference assignment conversion.

 

In general, object reference conversion is permitted when the direction of the conversion is ‘up’ the inheritance hierarchy; that is old type should inherit from the new type. The rules are:

  • An interface type may only be converted to an interface type or to Object. If the new type is an interface, it must be a super interface of the old type.

  • A class type may be converted to a class type or to an interface type. If converting to a class type, the new type must be a superclass of the old type. If converting to an interface type, the old type must implement the interface.

  • An array may be converted to the class Object, to the interface Cloneable, or to an array. Only an array of object reference types may be converted to an array, and the old element type must be convertible to the new element type.

 

 

 

OldType is a class

OldType is an interface

OldType is an array

NewType is a class

OldType must be a subclass of NewType.

NewType must be Object

NewType must be Object

NewType is an interface

OldType must implement interface NewType

OldType must be a sub-interface of NewType

NewType must be Cloneable/Serializable

NewType is an array

Compiler Error

Compiler Error

OldType must be an array of some object reference type that can be converted to whatever NewType is an array of.

 

 

Object method call conversion:  Rules are same as above.

 

To see how the rules make sense in the context of method calls, consider the extremely useful Vector class. You can store anything you like in a Vector (anything non-primitive) by calling the method

 

          addObject (Object ob);

 

whatever you pass to the above method, will be converted to Object. The automatic conversion means that the people who wrote the Vector class did not have to write a separate method for every possible type of object that anyone might conceivably want to store in a Vector.

 

Object reference casting:

 

Object reference casting is like primitive-casting: by using a cast, you convince the compiler to let you do a conversion that otherwise might not be allowed.

 

Any kind of conversion that is allowed for assignments or method calls is allowed for explicit casting, though it is not needed (done by compiler implicitly). The power of casting appears when you explicitly cast to a type that is not allowed by the rules of implicit conversion.

 

It is important to understand the difference between objects and object reference variables. Every object (almost) is constructed via the ‘new’ operator. The argument to the ‘new’ determines for all time the true class of the object. Java programs do not deal directly with the objects but with references to objects. The objects themselves live in memory somewhere in JVM. The reference variable contains something similar to the address of the object. This address is known as reference to the object. References are stored in variables, and variables have types that are specified by the programmer at compile time.

 

While an object’s class is unchanging, it may be referenced by variable of many different types.

 

The type of a reference variable is obvious at compile time. However, the class of an object referenced by such a variable cannot be known until runtime. This lack of knowledge is not a shortcoming of Java: it results from a fundamental principle of computer science.

 

The rules for casting are a bit broader than those for conversion. Some of these rules concern reference type and can be enforced by the compiler at compile time. Other rules concern object class and can only be enforced during runtime. The table below demonstrates compile time rules.

 

 

OldType is a non-final class

OldType is a final class

OldType is an interface

OldType is an array

NewType is a non-final class

OldType must extend NewType or vice versa

OldType must extend NewType

Always OK

NewType must be Object

NewType is a final class

NewType must extend OldType

OldType and NewType must be the same class

NewType must implement interface OldType

Compiler Error

NewType is an interface

Always OK

OldType must implement interface NewType

Almost always OK

OldType must be Object

NewType is an array

OldType must be Object

Compiler error

Compiler Error

OldType must be an array of some type that can be cast to whatever NewType is an array of.

 

Assuming that a desired cast survives compilation, a second check must occur at runtime. The second check determines whether the class of the object being cast is compatible with the new type.

 

Compile time rules:

 

  1. When both OldType and NewType are classes, one must be a subclass of the other.

  2. When both are arrays, both arrays must contain reference types, and it must be legal to cast an element of OldType to an element of NewType.

  3. You can always cast between an interface and a non-final object.

 

Runtime rules:

 

Remember that the conversion to NewType must actually be possible.

  1. If NewType is a class, the class of the expression being converted must be NewType or must inherit from NewType.

  2. If NewType is an interface, the class of the expression being converted must implement NewType.

 

 

 


 

section5-1-1 | section5-1-2 | section5-2 | section5-3 | section5-4

 

Sections : 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

 

 

 

 

 

 

 

Home | Blog | Java | Jokes | Poems | Musings | Site Map | Kudos | Downloads | Useful Sites | Interesting | System Setup | Contact  

Loading

 Number of Pages viewed on this site since January' 2003 : Hit Counter eXTReMe Tracker

For any queries, comments or suggestions, write to me .

This site never compromises your privacy, please read this site's privacy policy.