Site hosted by Angelfire.com: Build your free website today!
scjp section 5: operators and assignments
 
  • Determine the result of applying any operator (including assignment operators and instance of) to operands of any type class scope or accessibility or any combination of these.
  • Determine the result of applying the Boolean equals (Object) method to objects of any combination of the classes java.lang.String, java.lang.Boolean and java.lang.Object.
  • In an expression involving the operators &, |, &&, || and variables of known values state which operands are evaluated and the value of the expression.

Operators and Assignment

  1. Order of Precedence of Java Operators
    • evaluation is left to right
    • association of assignment is right to left
          e.g. int[] a = { 4, 4}; int b = 1; a[b] = b = 0;
               first gives a[1] = b = 0; then assigns b=0; and a[1]=0;
    • Order: highest at top
      Unary ++ -- +(unary positive) -(unary negative) ! ~(bitwise inversion) (type)(casting)
      Arithmetic * / %
      +
      (addition and String concatenation - promotions use toString(), via Object wrappers if primitives) -
      Shift << >> >>>(unsigned)
      Comparison < <= == >= > instanceof
      Bitwise & ^ |
      Short-circuit && ||
      Conditional ?:
      Assignment = op=

  2. General Rules
    • type in arithmetic operations is at least an int (unary can keep own type) - uses promotions
    • if divide an integral type by zero, get an ArithmeticException (a runtime exception, so doesn't need to be caught or declared)
    • if divide a floating point type by zero, get (POSITIVE|NEGATIVE)_INFINITY
    • don't get exceptions with over/underflow - if integral types, overflow drops off most significant bits, if floating points use infinity or NaN (e.g. for Math.sqrt(-2.0))
    • note: NaN cannot be compared so Float.NaN == Float.NaN returns false - to check for NaN in a result, use (Float|Double).isNaN(result)

  3. Shift Operators
    • uses: align bits for read/write to I/O ports, efficient * and / by 2x
    • bits that fall off end are discarded
    • new bits shifted in
      • for <<(left-shift) and >>>(unsigned right-shift) - all 0's
      • for >>(signed right-shift), if (before shift) a 1 was in most significant position (indicating a negative number), bring in 1's, else bring in 0's
    • note: -1/2 = 0 (rounds towards 0), but -1>>1 = -1 (rounds down)
    • val>>(bits) - if val is int (32-bits) then shfted by bits%32

  4. Arithmetic Promotion of Operands
    • takes place before any binay operation
    • always to at least an int type
    • consequences for unsigned right-shift of bytes and shorts:
          e.g. 11000000>>>(4), the byte first gets promoted to an int:
               11111111|11111111|11111111|11000000>>>(4) then get shift          00001111|11111111|11111111|11111100, and if follow by re-casting to a byte:          11111100, but would have expected 00001100

  5. Ordinal Comparisons (with < <= >= >)
    • arithmetic promotions (on numeric types only) e.g. 'A' >= 65.0F is true, as char is first promoted to unicode decimal (65) and then to 65.0F
    • cannot take boolean or class-type operands (except ==)

  6. The instanceof Operator
    • variable instanceof ClassName is either true or false
    • evaluates to true if variable
      • is an instance of ClassName
      • or an instance of a subclass of ClassName
      • or, if ClassName is an interface, an instance of an object that implements that interface
    • for arrays: variable instanceof Component[]
      • first tests if variable is an array
      • then tests if variable is of the same type, or subtype, of the Component
      • can test if something is an array with object.getClass().isArray()

  7. Equality Comparison Operators
    • primitive types - promotion first
    • objects
      • compare references to object, so true iff both point to the same object
      • use a.equals(b) (b instanceof a must be true)
      • must define equals method as taking an Object as argument (else would have simply overloaded, not overridden, the method) (should also define a int hashCode() if define an equals(Object o) method).
    • cannot compare primitives to objects
    • note: for Strings, compiler optimization only produces one object for each String literal, so:
          String a = "this"; String b = "this"; a == b; evaluates as true

  8. Bit-wise Operators: & ^ |
    • bitwise AND, XOR and OR

  9. Boolean Operations
    • & ^ | is AND, XOR, Or on the single bit of 2 booleans
    • short-circuit logical operators && and ||
      • right-hand operand will not evaluate if result got from only 1st left-hand operand defines result
          if left-hand operand true, don't need to evaluate rest of || (as will be true)
          if left-hand operand false, don't need to evaluate rest of && (as will be false)
      • good for handling null values if (s != null && s.length() > 0))...

  10. The Conditional Operator: ?:
    • value = (condition)?(val_if_true):(val_if_false);

  11. The Assignment Operators: == op=
    • op=
      • includes an implicit cast so byte b = 2; b += 3; will compile as second statement is equivalent to b = (byte)(b+3)
      • good if the variable is complex, eg. anArray[index]
    • assignment returns a value so a = b = 0 is assigned right to left

Converting and Casting

  1. Primitives and Conversion (implicit - compile-time)
    1. At Assignment or Method-call
      • a boolean can't be converted to any other type
      • for non-booleans - only widending conversions allowed
        the widening conversions
        note: byte|short to char are considered narrowing
      • by default, a literal is either an int or double, except jvm relaxes for integral types
    2. Arithmetic Promotion
      • for the unary operators, positive|negative|inversion(~), byte, short and char promoted to an int
      • for the binary operators (and comparisons) all converted to at least an int, or to the larger primitive type

  2. Primitives and Casting (explicit)
    • used when want to perform a narrowing conversion (including converting bytes/shorts to chars etc)
    • if have 1's in most significant bits, get chopped off
    • can cast between all primitive types (except booleans)

  3. Object Reference Conversion (implicit - compile-time)
    • At Assignment or Method-call only (no arithmetic promotion as can't be operands)
    • at compile-time
    • 3 different object reference types: class, interface and array
    • In general, object reference conversion occurs when directing of conversion is up the inheritance hierarchy. so:
      1. a class type may be converted to any class that is one of it's superclass's, or any interface as long as the class implements it
      2. an interface my abe converted to the class Object, or to an interface that is a superinterface of it
      3. an array may be converted to the class Object, to the interface Clonable or Serializable, or to any array of objects that can be converted to the new object type

  4. Object Reference Casting (explicit)
    • anything that would implicitly convert anyway is OK (though unnecessary)
    • Compile-time Rules:
      1. a non-final class can be cast into any class that it extends (ie. any superclass), or extends it (ie. any subclass, note that a final class cannot be subclassed), or to any interface, or to an array in an Object wrapper
      2. a final class can be cast to it's own type or to a subclass (not of itself, obviously) or to any interface
      3. an interface can be cast to any non-final class, to any final class that implements Serializable, or to any other interface
      4. an array can only be cast to a non-final class (as long as the array is referenced by an Object reference), or an array of object references that it's own references can be cast to
      5. note: you can always cast between an interface and a non-final object
    • Run-time Rules (throws Exceptions)
      1. if casting to a class, the underlying class|interface being converted must be th class itself, or inherit from it (i.e. be a subclass)
      2. if casting to an interface, the underlying class being cast must implement this interface

  • Determine the effect upon objects and primitive values of passing variables into methods and performing assignments or other modifying operations in that method.

Argument Passing

  • a copy of the primitive, or object refernce, gets passed to methods
  • for object references
    • can break the pointing to the method with either myObject = null; or myObject = new Object()
    • can alter the original object
    • most JVM's have an intermediary jvm reference to the object, that other references to the object actually reference