Chapter 3 Operators Notes Flashcards
TYPES OF OPERATORS
- unary
- binary
- ternary
OPERATOR PRECEDENCE
-
Post-unary operators
expression++, expression--
-
Pre-unary operators
++expression, --expression
-
Other unary operators
-, !, ~, +, (type)
-
Multiplication/division/modulus
*, /, %
-
Addition/subtraction
+, -
-
Shift operators
<<, >>, >>>
-
Relational operators
<, >, <=, >=, instanceof
-
Equal to/not equal to
==, !=
-
Logical operators
&, ^, |
-
Short-circuit logical operators
&&, ||
-
Ternary operators
boolean expression ? expression1 : expression2
-
Assignment operators
=, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, >>>=
LOGICAL COMPLEMENT AND NEGATION OPERATORS
- logical complement operator (!) flips the value of a boolean expression.
- negation operator, -, reverses the sign of a numeric expression
Examples:
int pelican = !5; // DOES NOT COMPILE boolean penguin = -true; // DOES NOT COMPILE boolean peacock = !0; // DOES NOT COMPILE
1 and true
In Java, 1 and true are not related
in any way, just as 0 and false are not related
.
int lion = 3; int tiger = ++lion * 5 / lion--; System.out.println("lion is " + lion); System.out.println("tiger is " + tiger);
Printed:
lion is 3 tiger is 5
arithmetic operators
All of the arithmetic operators may be applied to any Java primitives, with the exception of boolean. Furthermore, only the addition operators + and += may be applied to String values, which results in String concatenation.
Adding Parentheses
you can change the order of operation explicitly by wrapping parentheses
around the sections you want evaluated first.
Verifying Parentheses Syntax
- balanced parentheses
- left-parenthesis matching right-parenthesis.
long pigeon = 1 + ((3 * 5) / 3; int blueJay = (9 + 2) + 3) / (2 * 4; short robin = 3 + [(4 * 2) + 4];
- The first example does not compile because the parentheses are not balanced. There is a left-parenthesis with no matching right-parenthesis.
- The second example has an equal number of left and right parentheses, but they are not balanced properly. When reading from left to right, a new right-parenthesis must match a previous left-parenthesis. Likewise, all left-parentheses must be closed by right-parentheses before the end of the expression.
- The last example does not compile because Java, unlike some other programming languages, does not allow brackets, [], to be used in place of parentheses. If you replace the brackets with parentheses, the last example will compile just fine.
Division and Modulus Operators
System.out.println(9 / 3); // 3 System.out.println(9 % 3); // 0 System.out.println(10 / 3); // 3 System.out.println(10 % 3); // 1 System.out.println(11 / 3); // 3 System.out.println(11 % 3); // 2 System.out.println(12 / 3); // 4 System.out.println(12 % 3); // 0
jshell> 0/1 $17 ==> 0 jshell> 0/2 $18 ==> 0 jshell> 0 % 1 $19 ==> 0 jshell> 0 % 3 $20 ==> 0 jshell> 1 / 0 | Exception java.lang.ArithmeticException: / by zero | at (#21:1) jshell> 1 % 0 | Exception java.lang.ArithmeticException: / by zero | at (#22:1)
Exception java.lang.ArithmeticException: / by zero
The modulus operation is not limited to positive integer values in Java; it may also be applied to negative integers and floating-point numbers.
For example, if the divisor is 5, then the modulus value of a negative number is between -4 and 0.
For the exam, though, you are not required to be able to take the modulus of a negative integer or a floating-point number.
test
Numeric Promotion Rules
- If two values have different data types, Java will automatically promote one of the values to the larger of the two data types.
- If one of the values is integral and the other is floating-point, Java will automatically promote the integral value to the floating-point value’s data type.
- Smaller data types, namely, byte, short, and char, are first promoted to int any time they’re used with a Java binary arithmetic operator, even if neither of the operands is int.
- After all promotion has occurred and the operands have the same data type, the resulting value will have the same data type as its promoted operands.
What is the data type of x * y?
int x = 1; long y = 33; var z = x * y;
long
What is the data type of x + y?
double x = 39.21; float y = 2.1; var z = x + y;
This is actually a trick question, as this code will not compile!
Floating-point literals are assumed to be double, unless postfixed with an f, as in 2.1f.
What is the data type of x * y?
short x = 10; short y = 3; var z = x * y;
int
What is the data type of w * x / y?
short w = 14; float x = 13; double y = 30; var z = w * x / y;
double
CASTING VALUE
Casting is optional and unnecessary when converting to a larger or widening data type, but it is required when converting to a smaller or narrowing data type.
Examples of casting:
1: int fur = (int)5; 2: int hair = (short) 2; 3: String type = (String) "Bird"; 4: short tail = (short)(4 + 10); 5: long feathers = 10(long);
- Line 1, 2 and 3 are valid, spaces between the cast and the value are optional
- Line 4, since casting is a unary operation, it would only be applied to the 4 if we didn’t enclose 4 + 10 in parentheses.
- Line 5, does not compile because the type is on the wrong side of the value.
Why none of the following lines of code compile?
float egg = 2.0 / 9; // DOES NOT COMPILE int tadpole = (int)5 * 2L; // DOES NOT COMPILE short frog = 3 - 2.0; // DOES NOT COMPILE
All of these examples involve putting a larger value into a smaller data type.
Reviewing Primitive Assignments
int fish = 1.0; // DOES NOT COMPILE short bird = 1921222; // DOES NOT COMPILE int mammal = 9f; // DOES NOT COMPILE long reptile = 192301398193810323; // DOES NOT COMPILE
- The first statement does not compile because you are trying to assign a double 1.0 to an integer value.
- The second statement does not compile because the literal value 1921222 is outside the range of short
- The third statement does not compile because of the f added to the end of the number that instructs the compiler to treat the number as a floating-point value, but the assignment is to an int.
- the last statement does not compile because Java interprets the literal as an int and notices that the value is larger than int allows. The literal would need a postfix L or l to be considered a long.
Fix these statements:
int fish = 1.0; // DOES NOT COMPILE short bird = 1921222; // DOES NOT COMPILE int mammal = 9f; // DOES NOT COMPILE long reptile = 192301398193810323; // DOES NOT COMPILE
int fish = (int)1.0; //cast double to int and stored as 1 short bird = (short)1921222; // cast int to short and stored as 20678 int mammal = (int)9f; // cast float to int long reptile = 192301398193810323L; //add postfix L
OVERFLOW AND UNDERFLOW
Overflow is when a number is so large that it will no longer fit within the data type, so the system “wraps around” to the lowest negative value and counts up from there, similar to how modulus arithmetic works.
There’s also an analogous underflow, when the number is too low to fit in the data type, such as storing -200 in a byte field.
System.out.print(2147483647+1); // -2147483648
Since 2147483647 is the maximum int value, adding any strictly positive value to it will cause it to wrap to the smallest negative number.
Why line 3 and 4 does not compile?
1: short mouse = 10; 2: short hamster = 3; 3: short capybara = (short)mouse * hamster; // DOES NOT COMPILE 4: short gerbil = 1 + (short)(mouse * hamster); // DOES NOT COMPILE
- line 3, the cast applied to mouse, and mouse alone. After the cast is complete, both operands are promoted to int since they are used with the binary multiplication operator (*), making the result an int and causing a compiler error.
- line 4, casting is performed successfully, but the resulting value is automatically promoted to int because it is used with the binary arithmetic operator (+).
COMPOUND ASSIGNMENT OPERATORS
int camel = 2, giraffe = 3; camel = camel * giraffe; // Simple assignment operator camel *= giraffe; // Compound assignment operator
Compound operators are useful for more than just shorthand—they can also save us from having to explicitly cast a value.
Example:
long goat = 10; int sheep = 5; sheep = sheep * goat; // DOES NOT COMPILE
long goat = 10; int sheep = 5; sheep *= goat;
The compound operator will first cast sheep to a long, apply the multiplication of two long values, and then cast the result to an int.
ASSIGNMENT OPERATOR RETURN VALUE
One final thing to know about assignment operators is that the result of an assignment is an expression in and of itself, equal to the value of the assignment.
Example:
long wolf = 5; long coyote = (wolf=3); System.out.println(wolf); // 3 System.out.println(coyote); // 3
The key here is that (wolf=3) does two things.
First, it sets the value of the variable wolf to be 3.
Second, it returns a value of the assignment, which is also 3.
The equality operators are used in one of three scenarios:
- Comparing two numeric or character primitive types. If the numeric values are of different data types, the values are automatically promoted. For example, 5 == 5.00 returns true since the left side is promoted to a double.
- Comparing two boolean values
- Comparing two objects, including null and String values
object comparison
For object comparison, the equality operator is applied to the references to the objects, not the objects they point to. Two references are equal if and only if they point to the same object or both point to null.
a instanceof b
(object) instanceof (type)
Returns true if the reference that a points to is an instance of a class, subclass, or class that implements a particular interface, as named in b
It is considered a good coding practice to use the instanceof operator prior to casting from one object to a narrower type.
Invalid instanceof
One area the exam might try to trip you up on is using instanceof with incompatible types. For example, Number cannot possibly hold a String value, so the following would cause a compilation error:
public static void openZoo(Number time) { if(time instanceof String) // DOES NOT COMPILE ...
null and the instanceof operator
calling instanceof on the null literal or a null reference always returns false.
System.out.print(null instanceof Object); Object noObjectHere = null; System.out.print(noObjectHere instanceof String); System.out.print(null instanceof null); // DOES NOT COMPILE jshell> s instanceof null | Error: | illegal start of type | s instanceof null | ^
Tips to help you remember LOGICAL OPERATORS:
-
AND
(&)
is only true if both operands are true. -
Inclusive OR
(|)
is only false if both operands are false. -
Exclusive OR
(^)
is only true if the operands are different.
The logical operators, (&), (|), and (^), may be applied to both numeric and boolean data types;
For the exam, though, you don’t need to know anything about numeric bitwise comparisons
SHORT-CIRCUIT OPERATORS
The short-circuit operators are nearly identical to the logical operators, & and |, except that the right side of the expression may never be evaluated if the final result can be determined by the left side of the expression.
Avoiding a NullPointerException
if(duck!=null & duck.getAge()<5) { // Could throw a NullPointerException // Do something } if(duck!=null && duck.getAge()<5) { //if duck was null, then the short-circuit prevents a NullPointerException from ever being thrown, // Do something }
Checking for Unperformed Side Effects
int rabbit = 6; boolean bunny = (rabbit >= 6) || (++rabbit <= 7); System.out.println(rabbit);
Making Decisions with the Ternary Operator
booleanExpression ? expression1 : expression2
- The first operand must be a boolean expression
- the second and third operands can be any expression that returns a value.
For the exam, you should know that there is no requirement that second and third expressions in ternary operations have the same data types
TERNARY EXPRESSION AND UNPERFORMED SIDE EFFECTS
Notice that since the left-hand boolean expression was true, only sheep was incremented.
int sheep = 1; int zzz = 1; int sleep = zzz<10 ? sheep++ : zzz++; System.out.print(sheep+","+zzz); // 2,1
left-hand boolean expression evaluates to false, only zzz was incremented.
int sheep = 1; int zzz = 1; int sleep = sheep>=10 ? sheep++ : zzz++; System.out.print(sheep+","+zzz); // 1,2
For the exam, be wary of any question that includes a ternary expression in which a variable is modified in one of the right-hand side expressions.