Type Compatibility, Conversion, Assignment and Casts George Blank, Mike Meehan, Asra Sultana Variables and Types • A variable is a location in memory where values can be stored and referenced. • Variables are associated with types, which have particular data sizes and a restricted set of valid operations that can be performed on them. • Variable declarations assign an identifier, a type, and may declare an initial value. Many types have a default value. For example, an uninitialized integer defaults to 0. Variable (a memory location) a value (a default value) address a type a name (identifier) The address or value may be passed as a parameter Identifiers • Identifiers are used in Java to give a name to classes, methods and variables that can be used to access them. Java identifiers begin with a “letter,” followed by letters or digits. A Java “letter” includes the letters of any alphabet in Unicode plus the underscore _ and dollar sign $. • There is a Java standard naming convention for the use of identifiers, which can be found at http://java.sun.com/docs/codeconv/ Sample Code Standards • Here are a few examples of code standards from the section on declarations: – 6.1 Use one declaration per line to encourage comments – 6.2 Try to initialize local variables where they are declared – 6.3 Put declarations only at the beginning of blocks • There are a lot of details to learn, and it will take a while to be proficient in Java coding. Java Primitive Types • • • • Boolean: boolean Integer: byte, short, int, long Character: char Floating Point: float, double Type Compatibility • Two Types are compatible if values of one type can appear wherever values of the other type are expected, and vice versa. • Java is a strongly typed language and from there comes it’s safety and robustness. • Every variable has a type which is strictly defined. • All assignments ,whether explicit or via parameter passing in method calls ,are checked for type compatibility and any mismatches result in errors . Type Conversion in Primitive Types • Widening – When one type of data is assigned to another type of variable, an automatic(implicit) type conversion will take place if,the two types are compatible and the destination type is larger than the source type. – Example: int i; byte b; i=b; //valid conversion • Narrowing – Converting a value of larger range to value of smaller range. – Example: int i; byte b; b=i; //invalid Common misunderstanding • Implicit and explicit typecasting of primitive types is frequently misunderstood. • The next slide is a small test program, overloaded with multiple constructors to show when and how type conversion promotion is done with implicit casting. • In this example, since the third value is an integer, but there is no constructor that takes an integer, its value and the float value automatically convert to double. (Case 5: double, double, double) public class typetest { typetest(double a, double b, short c){ System.out.println("1 (dbl dbl short)"); } typetest(float a, byte b, long c) { System.out.println("2 (float byte long)"); } typetest(long a, long b, long c) { System.out.println("3 (long long long)"); } typetest(float a, long b, short c) { System.out.println("4 (float long short)"); } typetest(double a, double b, double c) { System.out.println("5 (dbl dbl dbl)"); } public static void main(String[] args) { typetest t = new typetest(); t.typetest(3.4, 3L, 3); } } Type Casting in Primitive Types • A cast is an explicit type conversion of incompatible types. • General form : (target-type)value Target-type is the desired type to convert the value to. • A different type of conversion called truncation will occur when a floating point value is assigned to an integer type. • If the size of the whole number is too large to fit into the target int type, then that value will be reduced modulo the target type’s range. Assignment • For type conversion and casting the Assignment Operator is used between the two values. • General form: var = exp • Example: int i=10; long m=10000L; double d=Math.PI;//PI=3.1415…. i=(int)m;//cast m=i;//widening m=(long)d;//cast d=m;widening Type Conversion in Expressions • In addition to assignments, type conversions may occur in expressions. • Promotion rules that apply to expressions: – – – – all byte and short values are promoted to int If one operand is long,the whole expression is promoted to long If one operand is a float ,the whole expression is promoted to float If one operand is double ,the whole expression is promoted to double Promotion rules example class Promote { Public static void main(String args[]){ byte b=12; char c=‘a’; short s=1004; int i=20000; float f=5.67f; double d=.1234; double res=(f*b)+(i/c)-(d*s); System.out.println(“result :” +res);} } Java Reference Types • In addition to the primitive types, Java allows types that are objects, and which can be user defined with a class definition. • Since objects can have a hierarchy, with supertypes and subtypes, some operations can be inherited by subtypes. Guidelines for this must be understood to avoid problems. The Object Type • All reference types are subclasses of the java.lang.Object type. • Any object may be referred to by a reference variable of type Object. • However, Objects have limited functionality, and it is advantageous to convert the generic Object to a more specific class, if possible. Type Casting Returns • Type casting comes in two flavors: narrowing and widening. • Narrowing casts force a variable of one type into a more restrictive structure (e.g. a parent class casted to a child class, or an interface casted to an implementing class). • Widening casts do the opposite, moving from a child class to a parent class. Son of Type Casting • It is generally safer to perform wider casts, and the JVM will handle them implicitly. • Narrowing requires explicit type casting, and may result in a ClassCastException. • Object thing = new String(); • String stringThing = (String) thing; • Thread bogus = (Thread) thing; // raises exception! Type Conversion • It most cases it makes sense to consider an Object in the context of several different types. • An integer may be represented as a long, a float, a double or a String. • Objects may be represented as integers when using Container classes. Conversion of Reference types • Widening – The conversion of a subtype to one of its supertypes is called widening. – The widening of reference types is always allowed and is carried out implicitly. • Narrowing – Conversion of supertype to one of its subtypes is called narrowing. (downcasting) – It requires explicit casting,it is allowed at compile time,it is not always safe and may result in runtime Exceptions. Sample code fragment class Student {..} //super class class Undergraduate extends student{..}//subclass class Graduate extends Student{..}//subclass // instances Student student1, student2; student1 =new UnderGraduate();//widening,valid student2 =new Graduate();//widening,valid Graduate student3; student3 = student2;//compilation error student3 = (Graduate)student2;//explicit cast //done,valid Polymorphic Assignment • Polymorphic Assignment Rule: – The type of the expression at the right hand side of an assignment must be a subtype of the type of the variable at the left hand side of the assignment. • In the previous example, • student3=(Graduate)student2; //compilation OK, //runtime exception • Downcasting results in exceptions being thrown,so,it should be done with proper care • There are two proper ways of downcasting. Proper ways of Downcasting • The pessimistic approach exp instanceof Type • instanceof operator is used to check the class of an object before downcasting • The expression returns true if exp is an instanceof a class or an interface type named Type. if(student1 instanceof Graduate){ Graduate gradStudent=(Graduate)student1; }else { //student1 is not a graduate student } Continue.. • The optimistic approach • ClassCastException is caught as follows, try{ //… Graduate gradStudent=(Graduate)student1; //… } catch(ClassCastException e){ //student1 is not a graduate student } Conversion Functions • Primitives have Object wrapper classes that facilitate type conversions. • The Integer class, for example is a wrapper for int. • An Integer may be used anywhere an Object is required (it extends java.lang.Object). Integer Class: Usage • • • • • • int i = 24; Integer aye = new Integer(7); Integer jay = new Integer(j); Integer kay = new Integer(“144”); String ess = aye.toString(); double dee = aye.floatValue() / jay.intValue(); • Distinguish between Integer and int! Integer Class: Static Methods • Static methods exist for on-the-spot type conversions: • System.out.println(Integer.toString(42)) ; • int bug = Integer.valueOf(“0xF00F”); • See also: java.lang.Number Type Assignment • Type conversion by assignment is a more restrictive form of type conversion. • Essentially, conversion by assignment may only occur in cases where the assigned type is wider than the assigning type. • A notable exception is in the conversion from int to byte, short, or char. Assignment is permissible if the int may be losslessly represented by the narrower class. Type Compatibility • After an iteration of development, it is possible that a class becomes incompatible with previous versions. • It is the responsibility of the new class to maintain compatibility with older versions. • Indicate incompatible versions of a class using the serialVersionUID. Managing Class Versions • Avoid incompatible changes as much as possible. • Serialize data in a format that is implementationagnostic (e.g. HashMap stores data in key-value pairs, rather than using an internal hash structure). • If an incompatible change in necessary, change the serialVersionUID and prepare to handle the invalidClassException References • Integer (Java 2 Platform SE v1.4.2). Sun Microsystems. 2003. 4/29/06 <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Int eger.html>. • Number (Java 2 Platform SE v1.4.2). Sun Microsystems. 2003. 4/29/06 <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Nu mber.html>. References, continued • Versioning of Serializable Objects. Sun Microsystems. 1997. 4/29/06 <http://java.sun.com/products/jdk/rmi/doc/serialspec/version.doc.html>. • Java Practices: Implementing Serializable. John O'Hanley. 2006. 4/29/06 <http://www.javapractices.com/Topic45.cjp>. References, continued • VM Spec Java Programming Language Concepts. Sun Microsystems. 1999. 4/29/06 <http://java.sun.com/docs/books/vmspec/2ndedition/html/Concepts.doc.html>. • Xiaoping Jia, Object Oriented Software Development Using Java. Addison Wesley, 2003 • Patrick Naughton and Herbert Schildt, Java 2: The Complete Reference, Third edition