OPERATORS AND ASSIGNMENTS
- You can use an object of one type wherever reference to one of its supertypes is required but not vice versa i.e. you can reference up the class hierarchy.
- Can assign null reference to any object reference.
- Widening primitive conversion
byte -> short -> int -> long -> float -> double (Important) char -> int -> long -> float -> double (Important)
- Narrowing primitive conversion
double -> float -> long -> int > char -> short > byte
- If the floating point value is NaN the result is an int or long value of zero.
- Widening reference conversion
- Can convert any class, interface or array reference to an Object reference
- Convert any class to any interface it implements.
- Convert any class, interface or array reference to null reference.
- Convert from any sub-interface to interface it extends.
- From any array to type Cloneable or type java.io.Serializable
- From any array of reference to any array of compatible reference.
- You cant instantiate an interface reference, as interfaces are abstract.
- Narrowing reference conversion
- Any class, interface or array reference to Object reference.
- Any superclass to subclass.
- From any non-final class to an interface as long as the class does not implement the interface.
- From any interface to any non-superinterface provided both interfaces did not have same method signatures.
- From any array reference to any other array reference provided types of each array are compatible.
- Every other type, including null can be converted to String .
- Forbidden conversions
- Reference to primitive.
- Primitive to reference.
- null to primitive.
- Reference or primitive to Boolean.
- boolean to primitive or reference.
- One class to another unless they have superclass/subclass relationship.
- Class to array unless class is Object .
- Unary operators when applied to byte , short and char numeric types results in operand being promoted to int .
- Unary promotion also applies to all shift operators.
- When operands are of different types, automatic binary numeric promotion occurs with the smaller operand type converted to the larger.
Examples producing compile-errors:
byte = byte + byte; // found int, required byte
int = float + int; // found float, required int
long = float + long; // found float, required long
float = double + float; // found double, required float
- Overflow and underflow condition never produces a runtime exception .
- ~ Bitwise complement.
- In all cases ~x equals (-x)-1 .
- Only used with integer values.
- Inverts the bits.
- ! Logical compliment.
- Logical compliment of a Boolean type.
- Negation of maximum negative int or long value is the same number itself.
long l = 0L;
i = -(-2147483648); // result: -2147483648
l = -(-9223372036854775808L) // result: -9223372036854775808;
- Negation of integers is similar to subtraction from zero.
- For floating-point negation is not similar to subtraction from zero.
- Prefix and postfix operators can be used on char types.
- If the value of the divisor in floating-point division is 0 no exception is thrown; the value of the results are as follows:
- Division of a positive floating-point value: POSITIVE_INFINITY
- Division of a negative floating-point value: NEGATIVE_INFINITY
- Division of a floating-point value by -0: POSITIVE_INFINITY
10.34 / 0 // result: Infinity
-10.34 / 0 // result: -Infinity
10.34 / -0 // result: Infinity
0 / 0 // result: NaN (Not a number)
- Modulo operation
- x % y is equivalent to x – ((int) (x/y) * y)
- can be used for integers and floating-point.
5 % 3 = 2 -5 % 3 = -2 5.0 % 3 = 2.0 -5.0 % 3 = -2.0 5.0 % 0 = NaN // not a number
- Any relational expression with NaN is false
- Positive and negative zero are considered equal therefore
-0.0 < 0.0 is false and -0.0 <= 0.0 is true
- Equality operator have lower precedence than the relational operators
- In equality operation if either operand is a Nan the result is false for == but true for !=
- instanceof Type conversion operator (Important)
• Left-operand must be a reference object or null; cannot use primitive types
• Right-operand must be a Class, Interface name or Array type
• Determines if the left-operand is an instance of the class, interface or array type specified by the right-operand
• Returns the boolean value true if:
• Left-operand is a class or subclass of the right-operand
• Left-operand is an interface or subinterface of the right-operand
• Left-operand is an array of the same class, subclass or interface, subinterface of the right-operand array type
- 12 assignment operators:
= *= /= %= += -= <<= >>= >>>= &= ^= |=
- All are used with primitive data types except = and += which can be used with Strings
- If everything in the left-operands type contract can be met through the contract of the right-operand type, then the assignment will work. It doesn’t matter if the right-operand type implements more than the left-operand type; as long as it implements what the left-operand type contract guarantees.
- The compiler treats the object on the right side of the assignment as if it was the same type as the object on the left side of the assignment. At runtime, the real class of the object is always used.
- An array can only be assigned to a variable of the same array type, of type Object, of interface Cloneable, or of interface java.io.Serializable
- A class may be assigned to an Interface type if the class implements the interface or one of it’s sub-interfaces
- A reference of any object can be cast to a reference of type Object
- A reference to an object can be cast into a reference of type ClassName if the actual class of the object, when it was created, is a subclass of ClassName
- A reference to an object can be cast into a reference of type InterfaceName if the class of the object implements Interface, if the object is a subinterface of InterfaceName or if the object is an array type and InterfaceName is the Cloneable interface
- If you cast up the class hierarchy you do not have to use the cast operator; if you are cast down the class hierarchy you must use the cast operator
- A cast may work at compile-time but fail at runtime if the actual class of the object cannot be converted legally
- While you can cast up and down the class hierarchy, you cannot cast sideways
- You can cast an object reference using String
- You cannot use String as a cast type for a primitive type
- To cast an object reference to an array type reference, the object must be an array of a component type that is compatible with the component type of the array type reference
- You cannot cast a primitive type to an object reference, or vice versa
- You cannot cast a boolean type to another primitive type
operand1 ? operand2 : operand3
- If one of operand2 or operand3 is a byte and the other a short, the type of the returned value will be a short
- If one of operand2 or operand3 is a null, the type of the return will be the type of the other operand
- If both operand2 and operand3 are different types, one of them must be compatible (castable) to the other type
- The + and += operators both work on Strings
- += only works with an initialized var
- Strings are objects , not primitive types, and are read-only and immutable ; the contents never change
- String variables store references to a string object NOT the string itself
- The String class creates a pool of Strings
- When you create a String by using the new operator or by using the + and += operators (the string is computed at runtime) you are implicitly telling the compiler to create a new String object
- When you create a String by assigning a string literal the compiler searches the existing string pool for an exact match. If it finds one, a new string is NOT created. Instead the variable is assigned a reference to the existing pooled string
- To actually compare the contents of String objects use the String method equals()
- By the rules of String Conversion any type can be converted to a string
- This includes the primitive types
- For primitive types, conversion occurs by the compiler calling Type.toString(x) behind the scenes.
- defined in java.lang.Object therefore inherited by all classes
- returns true if and only if the two variables being compared hold a reference to the same object
- To check if objects are of the same class use the Comparison operator: instanceof
- java.lang.String overrides the java.lang.Object equals() method to return true if and only if the objects being compared contain the same sequence of characters
- java.lang.Boolean overrides the java.lang.Object equals() method, returning true if and only if the Boolean objects represent the same boolean value
- all the primitive type wrapper classes override the Object.equals() method to compare the value of the objects; the default Object.equals() checks if the variables reference the same object
|Postfix|| . (params) expr++ expr–|
|Unary||++expr –expr +expr -expr ~ !|
|Creation or Cast||new (type)expr|
|Multiplicative||* / %|
|Shift||<< >> >>>|
|Relational||< > >= <= instanceof|
|Bitwise exclusive OR||^|
|Bitwise inclusive OR||||
|Assignment||= += -= *= /= %= >>= <<= >>>= &= ^= |=|
- Precedence can be overridden using parantheses
- when two operators of the same precedence are next to each other, associativity rules apply
- all binary operators (except assignment operators) are left-associative
- assignment is right-associative
- the operand of every expression is evaluated before the operation is performed except for the short-circuit operators (&&, ¦¦) and ternary operator
int i = 10;
int j = 12;
if( (i<j) ¦ (i=3) > 5 ) // value of i after oper: 3
if( (i<j) ¦¦ (i=3) > 5 ) // value of i after oper: 10
if( (i>j) & (i=3) > 5 ) // value of i after oper: 3
if( (i>j) && (i=3) > 5 ) // value of i after oper: 10
- with & and ¦ both operands are always evaluated
- with && and ¦¦ the second operand is only evaluated when it is necessary
- when you pass a primitive value to a method, a copy of the value is made available to the method, not the value itself
- any changes made to the value in the method do not affect the original value
- when you pass an object reference to a method, a copy of the reference is passed. Operations in the method which change the object reference do not affect the original; however, changes to the object itself within the method affect the original object
Page Visitors: 2999
Latest posts by Tomcy John (see all)
- A Guide to Continuous Improvement for Architects - February 2, 2023
- Cloud-first Architecture Strategy - January 26, 2023
- Architecture Strategy and how to create One - January 24, 2023