Pragmatic Programmer Issues

Java Specification – Types, Values, Variables (ch4)

Comments: 2

Last week I wrote JS-ch3 summary. Today I focus on chapter four. The chapter is about types, values and variables.

  • Java is strongly typed – every variable, expression has type that is known at compile type.
  • Classes and interfaces are loaded by class loaders. Each class loader defines its classes and interfaces. So class A loaded by loader L1 and the same class A loaded by loader L2 are different !!! . Due this correctly compiled code may fail.
  • Different parameterized types are implemented by the same class or interface at run time. (Type erasure). It is possible that variable of parameterized type refers to object that is NOT OF THAT parameterized type. Some of this issue I described here
  • Null type has no name, so it is impossible to declare a variable of the null type. Null reference can always be cast to any reference type.
  • Primitive type is predefined by the Java programming language and named by its reserved keyword.
  • Integer operators do not indicate overflow or underflow
  • Integer operators can throw exception, NullPointerException if unboxing of null reference, / and % throws ArithmeticException if right operand is zero. ++ and — throw OutOfMemoryError if boxing conversion has not sufficient memory. Other operator CAN NOT throw exception.
  • Float IEEE 754 defines also positive and negative zero 0.0 and -0.0, positive and negative infinities Float/Double.NEGATIVE_INFINITY and Float/Double.POSITIVE_INFINITY. And for a result of certain invalid operation such as dividing by zero Float.NaN and Double.NaN
  • Except NaN foating-point values are ordered : negative infinity, negative finite nonzero, positive and negative zero, positive nonzero, positive infinity.
  • Positive and Negative zero are equal so 0.0 == -0.0 is true, and 0.0 > -0.0 is false
  • NaN is unordered so <, <=, >, >=, == is always false and != is always true. And x != x returns true only if x is NaN.
  • Version 1.3 introduce Float.floatToRawIntBits and Double.doubleToRawLongBits so we can distinguish NaN
  • As with Integer operators, float operator throws exception, NullPointerException (unboxing null reference), ++ and — OutOfMemoryError. Over operators CAN NOT throw exception. Overflow produce signed infinity and underflows produce signed zero. Operation that has no mathematical representation produce NaN. All numeric operations with NaN produce NaN.
  • A cast of boolean value to type boolean or Boolean is allowed, no other casts on type boolean is allowed.
  • There are three kind of reference type: class type, interface type and array type. Reference type may be parameterized.
  • New class instance (String) is created when the string + operator is used in non-constant expression.
  • String + operator will convert the reference to String by invoking toString method or using “null” if reference is null !!! or the result of toString is null. So this program produce nullnull. nullnull
  • Object is superclass of all other classes. Variable can hold any other instances of class or the array
  • getClass() method returns the Class objects that represents the class of the object. A Class object exists for each reference type. It can be used to discover fully qualified name of the class, its members its immediate superclass, its interfaces
  • static synchronized use lock associated with the Class object of the class.
  • Type intersection & provides option to multiply types (e.g. in generics). It is not possible to write an intersection type directly as part of program because no syntax supports this.
  • Parameterized type consist of name and type argument list. It is compile time error if name isn’t generic type or list size differs from the number of declared parameters.
  • Wildcards are useful when only partial knowledge about type is required
  • Collection<?> unbound wildcard allows any kind of collection. But accessed as Object.
  • ? extends B is upper bound and ? super B is lower bound
  • Type erasure is mapping from types (parametrized, and type variables) to types (never parameterized or type variables).
  • Because of type erasure not all types are available at run time. Types that are available are called reifiable types.
  • Type is reifiable if
    • It is non-generic
    • It is parametrized in which all type are unbounded <?>
    • It is raw type
    • It is primitive type
    • It is array type whose component is reifiable
  • Raw type is name of generic type with no parameters or any non-static type member (inner class) of raw type
  • The use of raw types is allowed only for compatibility of legacy code. Use of it is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw type
  • It is compile type error to attempt to use a type member of a parameterized type as a raw type.
  • Access to members of a raw type results in warning messages:
    • invocation of method or constructor of a raw type (unchecked warning) if erasure changes any of the types of any argument.
    • assignment to a field of raw type (unchecked warning) if erasure changes field type.
  • The subtype and supertype are binary relation on types. Note: Subtyping does not extend through generic types.
  • The following rules define the direct subtype among array types:
    • S > T than S[] > T[]
    • Object > Object[] also for p[] where p is primitive type
    • Clonable > Object[] also for p[] where p is primitive type
    • Serializable > Object[] also for p[] where p is primitive type
  • Type are used in declarations or in certain expressions, here is list:
    • Imported types (Declaration)
    • Fields both class and instance variables or constants of interface (D)
    • Constructor and method parameters (D)
    • Method results (D)
    • Local variables (D)
    • Exception handler parameters (D)
    • Type variables (D)
    • Class or Generic class or Array instance creations (Expression)
    • Generic method or constructor invocation (E)
    • Casts (E)
    • instanceof operator (E)
    • As arguments to parameterized types (E)
  • Variable is storage location and has associated type. Variable’s value is changed by assignment or by prefix or postfix operator
  • All assignments to a variable are checked for compatibility usually at compile time, but in case arrays a run time check is made.
  • Assignment from a value of a raw type to a variable of a parameterized type should only be used when combining legacy code which does not make use of parameterized types !!!
  • There are seven types of variables:
    • class variable -> declared using static keyword for class or defined in interface !!!. Initialized on class/interface preparation, destroyed on class/interface is unloaded
    • instance variable -> declared without static keyword. Initialized on instance creation. Destroyed after object finalization
    • array components -> Initialized on creation, destroyed when no longer referenced
    • method parameters -> created and initialized on every method invocation, destroyed then the method is completed.
    • constructor parameters -> same as method
    • exception handler parameter -> created each time an exception is caught, destroyed when block associated with catch is completed.
    • local variable -> decalared by declaration statement must be initialized before use, destroyed when variable block is finished
  • Exception to last rule is switch statement, because some block may bypass all variables are defined as one block.
  • final declares variable that can be assigned only once. Object referenced but such variable can change but reference to it CAN NOT.
  • Declaring a variable final can be useful documentation that value will not change and can help avoid errors.
  • Defaults

    • for byte it is (byte)0
    • short -> short(0)
    • int 0> 0
    • long -> 0L
    • float -> 0.0f
    • double -> 0.0d
    • char -> ‘\u0000’
    • boolean -> false
    • reference type -> null
  • Every variable and every expression has a type that can be determined at compile time.
  • Array has a class and it name is strange. For example for int[] it will be “[I” wanna know why read here There are more strange letters for arrays.

Very long chapter. See you soon.




Thanks for adding this 🙂 and your suggestion with PDF on the end is great. I’ve just write it on my todo list.


Great extract.
I would add a note that (AFAIK) to check for NaN and other special values we should use the .isNaN or .isInfinite methods.

BTW – maybe You plan to gather all java-specification-chapter-extract into one PDF after You finish that series? that would be great for me and I think not only 😉