Skip to content

Instantly share code, notes, and snippets.

@edefazio
Created October 10, 2015 18:22
Show Gist options
  • Save edefazio/b703bca7443621fd205b to your computer and use it in GitHub Desktop.
Save edefazio/b703bca7443621fd205b to your computer and use it in GitHub Desktop.
Static Typing (Implicit Casting) in Java illustration
package invariant;
/**
* Static Typing and Java
*
* Here are some of the purported POSITIVES of STATIC TYPING:
* <UL>
* <LI>PREVENT and DETECT ERRORS (checked at compile type) (i.e. CORRECTNESS)
* <LI>easier to REASON about the PROGRAM / METHOD
* <LI>easier to DEBUG
* <LI>better DOCUMENTATION
* <LI>easier COMPILER OPTIMIZATIONS (e.g. replacing virtual calls by direct calls when the exact type of the receiver is known statically)
* <LI>better RUNTIME EFFICIENCY
* </UL>
*
* ...there are ALSO some NEGATIVES to STATIC TYPING
* <UL>
* <LI>Too RIGID (as compared to dynamic typing)
* <LI>LESS REUSEABLE CODE (leads to Code Duplication )
* <LI>Too HARD TO ADAPT to changing /dynamic behavior
* </UL>
*
* This Gist illustrates one ACTUAL use case and describes how the code
* attempts to navigate the positives and negatives of static typing in
* Java's type system.
*
* There are some inconsistencies and sometimes Java makes ASSUMPTIONS
* ABOUT PROGRAMMER INTENT in an attempt to allow the reuse of code to either
* POSITIVE or NEGATIVE EFFECT. Other times Java requires the code be EXPLICIT
* to VERIFY
*
* @author M. Eric DeFazio eric@typefra.me
*/
public class StaticTypeChecking_2
{
enum ANumber { ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE };
public static void main (String[] args)
{
squareRoot( 9L ); // 1) type checker verifies that 9L is valid
// for the squareRoot() method "function domain"
// prints 3.0
squareRoot( 9 ); // 2) type checker does an implicit int-> long conversion
// sensing the programmer "intent" and allowing
// the sqaureRoot method to be reused for (int, short, byte, char)
// primitive types.
// prints 3.0
squareRoot ( (short)9 ); // 3) static typing does short -> long conversion
// prints 3.0
squareRoot ( (byte)9 ); // 3) static typing does byte -> long conversion
// prints 3.0
//this number literal 123982901299 is not within 32-bit int range
//and therefore this wont compile since Java assumes all literals are 32-bit ints
squareRoot ( 123982901299 ); //Note: Above the method (at runtime) did a int -> long
// conversion when i called sqaureRoot with an int.
// ...BUT in this case, Java requires that you
// are explicit when declaring a literal
// even though we KNOW the literal is being passed
// into a method that accepts a long value.
// COMPILATION ERROR
squareRoot ( 123982901299L );// By being explicit with a postfix 'L' to the literal
// the compiler knows to represent 123982901299
// as a 64-bit long.
// prints 352112.0578722064
squareRoot( '9' ); //3) '9' is a char, it will compile and run
// ...BUT all chars are ALSO an unsigned 16-bit numbers [0, 65535]
// prints 7.54983443527075
// (BUT WE MIGHT EXPECT it to print 3.0, even though Java assumed
// we wanted to evaluate the char as a 16-bit unsigned number)
System.out.println ( (int)'9' ); //...BECAUSE '9' == 57 (as an unsigned 16-bit number)
// and the squareRoot( 57 ); == 7.54983443527075
//this won't compile because of static type checking ("String" is not compatible with int/long)
//even though what is represented by "9" is a single char...
squareRoot("9"); // even though a String is "really" a sequence of characters
// COMPILATION ERROR
squareRoot ( Long.parseLong( "9" ) ); // we must explicitly use this conversion on
// a String to convert it to a Long
// prints 3.0
squareRoot ( ANumber.NINE ); // Java does not automatically ASSUME / convert an ENUM
// to its ordinal value
squareRoot ( ANumber.NINE.ordinal() ); // so can Explicitly do this to circumvent the problem
}
/**
* this is a simple method to illustrate static typing
* in Java
* @param longParameter
*/
public static void squareRoot ( long longParameter )
{
//Math.sqrt accepts double
//Java does an (implicit cast) from long -> double
//BEFORE calling Math.sqrt()
System.out.println ( Math.sqrt( longParameter ) );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment