|
|
Operators and Assignments - Assignment Operators
- 12 assignment operators:
= *= /= %= += -= <<= >>= >>>= &= ^= |=
- all are right-associative ie a=b=c groups as a=(b=c) vs (a=b)=c except the simple assignment operator = which is left-associative
eg a+b+c = (a+b)+c
- all are used with primitive data types except = and
+= which can be used with Strings
- all operators of the form op = cast their result to the type of the left-operand
- there is no implicit cast with the simple assignment operator =
- in all cases, x oper= y is equivalent to x = x oper y
For Example:
x += y is equivalent to x = x + y
x %= y is equivalent to x = x % y
x |= y is equivalent to x = x | y
Rules for Simple Assignment and Object references
- if the left-hand operand is a class, the right-operand must be either a null, or of the same class or subclass type as the class of the left-operand
- if class B extends class A,
A a = new B() is ok
as class B is guaranteed to fully implement class A
- B b = new A() is not ok
as there is no guarantee that the new A object will implement everything in class B
- if the left-hand operand is an interface, the right-operand must be either a null, or of the same interface or superinterface of the left-operand, or, a class that implements the interface or it's superinterface
- if interface InB extends InA, class C implements InA, and class D implements InB
InA inA = new C(); is ok
as class C guarantees to implement everything in interface InA
InB inB = new C(); is not ok
as the new C is not guaranteed to implement everything in interface InB
- InA inA1 = new D(); is ok
as class D is guaranteed to implement everything in interface A through it's implementation of InB which extends InA
class A{}
class B extends A{}
interface InA {}
interface InB extends InA {}
class C implements InA {}
class D implements InB {}
A a1 = new B(); // B is a subclass of A
// B b1 = new A(); // incompatible types
InA inA = new C(); // C implements InA
InB inB = new D(); // D implements InB
InA inA2 = new D(); // D implements InA as a superinterface
// InB inB2 = new C(); // incompatible types
inA = inB; // InA is a superinterface of InB
// inB = inA; // compile-error: incompatible types
Object o1 = inA; // an Object type can take any reference
Object o2 = inB;
Object o3 = new C();
C c = new Object(); // incompatible types
B b2 = null; // any object reference can take a null
InA inA3 = null;
| Summary |
- 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.
|
| !!! Warning !!! |
- 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.
|
Class of object a1 -> Class B // declared type was Class A
Class of object o1 -> Class D // declared type was Object
Class of object o2 -> Class D // declared type was Object
Class of object o3 -> Class C // declared type was Object
Array assignments (JLS §5.2)
- 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
int intArr[] = { 1,2,3 };
int intArr1[] = intArr; // compiles ok
// String arr[] = new A(); // incompatible types
// String arr[] = inA; // incompatible types
Object obj = intArr; // compiles ok
// inA = intArr; // incompatible types
Serializable inS = intArr; // compiles ok
Cloneable inC = intArr; // compiles ok
Also see
Example Code
Tips
- a class may be assigned to an Interface type if the class implements the interface or one of it's sub-interfaces
Traps
- assigning subclasses with the same parent to each other
- assigning a parent class to a subclass without a cast
|