<Previous    Back to Start  Contents   Next>

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.

Most of the operators are fundamental Java, so consult a textbook or tutorial if you are unsure of them. Here is information on some them, and notes on promotion rules.

Applying the '>>', '>>>' and '<<' operators to an int value specified as a bit pattern.

These operators are followed by a number which defines by how many bits the number is shifted.

>> performs a signed right-shift, that is, if the most significant (i.e. first on the left) bit is 1, then when it right-shifts the bits, it fills in a 1s on the left. If the most significant bit is 0, then when it right-shifts the bits, it fills in a 0s on the left. As the first bit represents the sign of a number (positive or negative), this preserves the sign of the number.

>>> performs an unsigned right-shift, it always fills in 0s on the left.

<< performs a left-shift (it always fills in 0s on the right).

The + operator

Adds. If any of the variables are Strings, it converts the non-Strings to Strings, and concatenates (joins) them.

Using the '==' comparison operator with two objects of any type.

With Objects, == determines whether the variables reference the same object in memory, rather than comparing their contents in a meaningful way. If you assign a=b, then a==b will evaluate to true, where a and b are objects.

Note that if you construct two Strings with the same String literal, without using the new keyword, e.g.

	String a = "Hello"
	String b = "Hello"

, then Java creates only one String object, so a==b evaluates as true.

Using the ternary operator.

This consists of a boolean expression, followed by question mark, then two expressions, seperated from each other by a colon. If the boolean expression before the question mark evaluates as true, the value from the expression before the colon is used, otherwise the value from the last expression is used. Example:

int a = true ? 1 : 0;
int b = false ? 1 : 0;
a will be 1. b will be 0.

When assignment is permitted between any two variables of possibly different types.

Primitives: You cannot assign booleans to any other type. With the exception that you cannot assign a byte to a char, you can assign a variable of type X to type Y (i.e. Y=X) only if Y is 'wider' than X. 'Wider' means that the primitive type can contain a wider range of values. The primitives, in order of 'width' are char/short, int, long, float, double. Note that you cannot assign a char to a short or vice versa.

Objects: You can assign object X to object Y (i.e. Y=X) only if they are of the same class, or X is a subclass of Y (called "upcasting").

Effect of assignment and modification operations upon variables .

In an arithmetic statement, variable may be widened automatically, to evaluate the expression (note the variables themselves aren't change, i.e. byte b is still a byte afterwards, but for its calculations Java uses a widened value). This is called promotion. Bytes, shorts and chars are always converted to ints, in unary (e.g. x++)or binary operations (e.g. x*y). For binary operators, if one operand is wider, the other is widened to the same type.
This has import consequences. For example:

byte b = 3;
b = b + 5;
will not compile, because the result of b+5 is an int.

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.

Unless it is overridden, the equals() method behaviour in Object, and therefore inherited from it, performs the same reference comparison as the == operator. However, the Boolean and String classes override this with a more meaningful comparison. equals()returns true, in Booleans if the two objects contain the same Boolean value, and in String if the Strings contain the same sequence of characters.

Note that StringBuffer does not override the equals() method, so if you use this method, it will not compare the actual text characters that the StringBuffers contain.

In an expression involving the operators &, |, && and ||, state which operands are evaluated and determine the resulting value of the expression.

Just a quick note on the second two operators: && (AND) and || (OR) are the short circuit operators, which do not evaluate the second operand if it is not necessary. AND is only true if both values are true, therefore if the first is false, the result is false, and there is no need to evaluate the second part. OR is true if either value is true, therefore if the first is true, the result is true, and there is no need to evaluate the second part.

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

When passed to a method, primitives may be promoted, and objects may be upcast, to the type/class that the method takes, if possible. For example, if a method takes an int as an argument, and you pass it a byte, the value passed to the method is the byte converted to an int. The rules for when this is allowed are as per the objective "Determine if an assignment is permitted between any two variables of possibly different types" above.

Note that primitive variables, in the calling method, are unaffected by modifications made in the target method. This is called passing by value. Look at this code:

void methodA() {
	int x=5;

void methodB(int x) {
	int x=10;
If you execute methodA(), it will print out "5". This is because it is the value of the variable x (which is 5), that is passed to methodB(). methodB() accepts this value into a local variable, which is coincidentally named x aswell. But it is a different variable. Subsequent changes inside methodB() will not change the value of x in methodA().
This issue is more complex where objects are concerned. Strictly speaking, they too are passed by value, like primitives. However, the value in question, where object variables are concerned, is in fact the memory location of the object that the variable points to. First, lets look at an example which acts like the above, but with objects. The Price class just stores the value assigned to it (using its constructor) as a member variable. The toString() method has been overwritten to return this value. It also has a setPrice() method to change its value.
void methodA() {
	Price x = new Price(5);

void methodB(Price x) {
	Price x = new Price(10);
This example, just like the one above, will print out "5". Note that the value being passed here to methodB() is in reality the location of the Price object in memory. In methodB(), the local variable x is re-assigned to point to a new Price object, but what methodA() sees is unaffected. This is made obvious here by the use of the new keyword. On the other hand, if you do operations which modify the object in the target methods, those changes will be visible in the calling method, as in the following example:
void methodA() {
	Price x = new Price(5);

void methodB(Price x) {
This will print out "10". Again methodB() is passed the location of the Price object, which it holds in a local variable x. However, when you call the setPrice() method, this change goes out to the actual object in memory, and hence methodA() sees the same new value, 10.

<Previous    Back to Start  Contents   Next>

©1999, 2000, 2002 Dylan Walsh.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being the disclaimer, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".