Type Safety and Enumerations Type Checking and Type

  • Slides: 20
Download presentation
Type Safety and Enumerations

Type Safety and Enumerations

Type Checking and Type Errors The type system defines data types and the operations

Type Checking and Type Errors The type system defines data types and the operations on data types. q A type error occurs if an operation is performed on a value where the operation isn't defined or not welldefined. n char c; scanf("%f", &c); /* error: double => char */ q The translator (compiler, interpreter) seeks to avoid type errors by type checking. n Type checking can be done statically or dynamically. q Languages like Java also catch type errors at run-time and raise ("throw") exceptions. q

Run-time Type Checking Student s = new Student("joe"); Object o = s. clone(); JFrame

Run-time Type Checking Student s = new Student("joe"); Object o = s. clone(); JFrame t = (JFrame) o; throws a Class. Cast. Exception

Type Safety (1( A program is considered "type safe" if it can be verified

Type Safety (1( A program is considered "type safe" if it can be verified that it is free of type errors. q In strongly typed languages like Java, this would seem like an easy task. . . but its not! q Is the java. util. Array. List class type safe? q

Type Safety (2( q Is the java. util. Array. List class type safe? java.

Type Safety (2( q Is the java. util. Array. List class type safe? java. util. Arrays from the Java 2 SDK API static void sort( Object [ ] array ); import java. awt. Color; . . . Object [ ] a = { new Double(0. 5), Color. RED, "hello" }; java. util. Arrays. sort( a ); // run-time Class. Cast. Exception !

Type Safety (2( Arrays. sort throws a Class. Cast. Exception. q Programmer isn't required

Type Safety (2( Arrays. sort throws a Class. Cast. Exception. q Programmer isn't required to catch Runtime. Exceptions, so this will compile OK but fail at run-time. Another example: q Is the java. util. Date class type safe? q java. util. Date from the Java 2 SDK API public Date(int year, int month, int day); // Date(year-1900, month /* jan=0, feb=1 */, dom ) int year = 2000; int month = 0; // jan = 0, feb = 1, mar = 2, . . . int day = 1; // day of month Date newyear = new Date( year - 1900, month, day );

Type Safety (3( q But, its sooo easy to forget. . . n Date(

Type Safety (3( q But, its sooo easy to forget. . . n Date( year, month, day ) ? ? ? n Date( day, month, year ) ? ? ? n Date( month, day, year ) ? ? ? int year = 2000 - 1900, month = 0, day = 1; Date d 1 = new Date( year, month, day ); Date d 2 = new Date( day, month, year ); Date d 3 = new Date( month, day, year ); d 1. to. String() --> "Sat Jan 01 00: 00 ICT 2000" d 2. to. String() --> "Wed Apr 10 00: 00 ICT 1901" d 3. to. String() --> "Fri May 11 00: 00 ICT 1900" more coffee, please

Type Safety (4( q q Calendar class has static constants for the months, but

Type Safety (4( q q Calendar class has static constants for the months, but the values are same as "int". n Calendar. JANUARY = 1 n Calendar. FEBRUARY = 2 They doesn't help type checking or type safety. int year = 2000 - 1900, month = 0, day = 1; Date d 1 = new Date( year, Calendar. JANUARY, day ); Date d 2 = new Date( day, Calendar. JANUARY, year ); Date d 3 = new Date( Calendar. JANUARY, day, year ); Its your fault!!!! You should have been more careful.

Enumerations: promoting type safety q Enumerated types were introduced in Pascal. type months =

Enumerations: promoting type safety q Enumerated types were introduced in Pascal. type months = ( jan, feb, mar, apr, . . . , dec ); procedure date(Year: int; Month: months; Day: int) begin. . . end; (* main method *) var thismonth : months; (* variable of months type *) begin No brainer! thismonth : = jan; date(2000, thismonth, 1); compiler can verify argument is valid.

Java Enumerations: enum q "enum" is like a class when static instances of itself.

Java Enumerations: enum q "enum" is like a class when static instances of itself. public enum Month { /* the allowed values of this type: */ JANUARY, FEBRUARY, MARCH, The values of this enumeration APRIL, . . . DECEMBER; } public class My. Date { int year = 2005; Month month = Month. DECEMBER; int day = 9;

enum can have attributes, too q set the attributes in a constructor: public enum

enum can have attributes, too q set the attributes in a constructor: public enum Month { /* the allowed values of this type: */ JANUARY("January", 0), FEBRUARY("February", 1), MARCH("March", 2), . . . DECEMBER; /* attributes */ public final String name; private int index; /* the constructor */ Month( String name, String index) { this. name = name; this. index = index; }

enum members are printable If an enum has a to. String( ) method, it

enum members are printable If an enum has a to. String( ) method, it is used. q If an enum doesn't have to. String( ), the enum member name is printed! q System. out. println( Month. JANUARY ); System. out. println( Month. JANUARY. name ); Output: JANUARY January

A Safer Date Class public class My. Date { /* attributes */ private int

A Safer Date Class public class My. Date { /* attributes */ private int year; private Month month; private int day; /* the constructor */ public My. Date( int year, Month month, int day) { this. year = year; this. month = month; this. day = day; } public String to. String() { return ""+day+" "+month. name+" "+year; } }

My. Date q q My. Date requires that the 2 nd argument be a

My. Date q q My. Date requires that the 2 nd argument be a month: programmer can put in an invalid value. My. Date my = new Date(2005, Month. MAY, 1); Use the ". name" property to print month as string. My. Date d 1 = new My. Date( 2005, Month. DECEMBER, 9 ); My. Date d 2 = new My. Date( 2005, 12, 9 ); // Error System. out. println( "Today is " + d 1); Today is 9 December 2005

enum values() method q Java automatically supplies a method named values() that returns an

enum values() method q Java automatically supplies a method named values() that returns an array of all values in the enumeration. For the Month enum : Month [ ] mlist = Month. values( ); for( Month m : Month. values() ) // loop for all values System. out. println( m ); JANUARY FEBRUARY MARCH APRIL MAY JUNE. . .

enum for Token Types q Good OO design: object contains its own properties public

enum for Token Types q Good OO design: object contains its own properties public enum Token. Type { /* the allowed values of this type: */ IDENT( "[A-Za-z_]\w*" ), NUMBER( "(\d+\. ? |\. \d)\d*([Ee][+-]? \d+)? " ), OPERATOR( "[-+*/^]" ), ASSIGN( "=" ), SEPARATOR( "[()]" ); /* attributes */ public final String regex; public final Pattern pattern; /* constructor */ Tokens( String regex ) { this. regex = regex; this. pattern = Pattern. compile(regex); }

Using Token Types q enum members are unique. You can use '==' to test

Using Token Types q enum members are unique. You can use '==' to test if ( token. type() == Token. Type. IDENT ). . . if ( token. type() == Token. Type. NUMBER ). . . public class Token { /* token has a type and value */ private Token. Type type; private String value; Token(Token. Type type, Double value) { this. type = type; this. value = value; } /* return the token type */ Token. Type type() { return type; } }

Advantages of using Enumeration 1. Type safety. 2. Collect all properties of a token

Advantages of using Enumeration 1. Type safety. 2. Collect all properties of a token in a single place (token name, token regular expression, . . . ) 3. More efficient than using String for testing. 4. Avoid mistyping of String name in comparison. Compare: if ( token. type. equals("NUMBER") ). . . if ( token. type. equals("IDENT") ). . . If you use the wrong string value then the error is not detected, but the code won't work. if ( token. type == Token. NUMBER ). . . if ( token. type == Token. IDENT ). . .

How to Hide the enum q To minimize changes in your program, you can

How to Hide the enum q To minimize changes in your program, you can try. . . public class Token { public static Token. Type IDENT = Token. Type. IDENT; public static Token. Type NUMBER = Token. Type. NUMBER; . . . /* can make "type" attribute immutable public */ public final Token. Type type; . . . } if ( token. type == Token. IDENT ). . . if ( token type == Token. NUMBER ). . . same as Token. Type. NUMBER

Compare all token types q In your tokenizer class, you can use values: ()

Compare all token types q In your tokenizer class, you can use values: () public class Tokenizer { String s; Token. Type type = null; . . . /* can make "type" attribute immutable public */ for ( Token. Type t : Token. Type. values() ) if ( s. matches( t. regex ) ) type = t; token = new Token( s, type );