Java 101: Foundations

Java 101: Evaluate Java expressions with operators

Operators and operator type conversion in compound Java expressions

Java applications process data by evaluating expressions, which are combinations of literals, method calls, variable names, and operators. Expression evaluation typically produces a new value, which can be stored in a variable, used to make a decision, and so on. In this second article in the Java 101: Foundations mini-series, I'll show you how to create expressions for your programs. Many expressions involve operators, including additive, array-index, bitwise, conditional, and equality types. I'll introduce each operator and its operands, and also discuss important concepts such as operator overloading and operator precedence. We'll conclude with a primer on operator type conversion, including a small program that you can use to practice type conversions on your own. Note that examples in this article are based on Java 8.

Evaluating simple expressions

A simple expression is a literal, variable name, or method call. No operators are involved. Here are some examples of simple expressions:

52                         // integer literal
age                        // variable name
System.out.println("ABC"); // method call
"Java"                     // string literal
98.6D                      // double precision floating-point literal
89L                        // long integer literal

A simple expression has a type, which is either a primitive type or a reference type. In these examples, 52 is an integer (int), System.out.println("ABC"); is void (void) because it returns no value, "Java" is a string (String), 98.6D is a double precision floating-point value (double), and 89L is a long integer (long). We don't know age's type.

Evaluating compound expressions with operators

A compound expression consists of one or more simple expressions connected to a larger expression via an operator, which is a sequence of instructions symbolically represented in source code. The operator transforms its expression operand(s) into another value. For example, in 6 * 5, the multiplication operator (*) transforms operands 6 and 5 into 30.

Compound expressions can be combined into larger expressions. For example, 6 * 5 + 10 presents compound expression 6 * 5 and a compound expression consisting of their product, addition operator +, and 10. The order of their evaluation (multiply first and then add) is dictated by Java's rules of precedence, which we'll get to shortly.

Java's operators are classified by their number of operands. Operators with one operand (e.g., unary minus [-], as in -5) are unary operators. Operators with two operands (e.g., multiplication and addition) are binary operators. Finally, operators with three operands (e.g., conditional [?:]) are ternary operators.

Java's operators are also classified by position. A prefix operator is a unary operator that precedes its operand (e.g., -5), a postfix operator is a unary operator that follows its operand (e.g., age++; -- add 1 to age's numeric value), and an infix operator is a binary or ternary operator between the operator's operands (e.g., age + 5).

Java provides many operators, which I discuss in the following sections.

Source code for "Java 101: Evaluate Java expressions with operators." Created by Jeff Friesen for JavaWorld.

Additive operators

The additive operators increase or decrease a numeric value through addition and subtraction. Additive operators include addition (+), subtraction (-), postdecrement (--), postincrement (++), predecrement (--), and preincrement (++). String concatenation (+) is also considered to be additive. Here's a formal definition for each of these operators:

  • Addition: Given operand1 + operand2, where each operand must be of character or numeric type, add operand2 to operand1 and return the sum. Example: 4 + 6.
  • Subtraction: Given operand1 - operand2, where each operand must be of character or numeric type, subtract operand2 from operand1 and return the difference. Example: 4 - 6.
  • Postdecrement: Given variable--, where variable must be of character or numeric type, subtract 1 from variable's value (storing the result in variable) and return the original value. Example: x--;.
  • Postincrement: Given variable++, where variable must be of character or numeric type, add 1 to variable's value (storing the result in variable) and return the original value. Example: x++;
  • Predecrement: Given --variable, where variable must be of character or numeric type, subtract 1 from its value, store the result in variable, and return the new decremented value. Example: --x;
  • Preincrement: Given ++variable, where variable must be of character or numeric type, add 1 to its value, store the result in variable, and return the new incremented value. Example: ++x;.
  • String concatenation: Given operand1 + operand2, where at least one operand is of String type, append operand2's string representation to operand1's string representation and return the result. Example: "A" + "B".

The addition, subtraction, postdecrement, postincrement, predecrement, and preincrement operators can generate values that overflow the limits of the result type. For example, adding two large positive 64-bit integer values can produce a value that cannot be represented in 64 bits. The resulting overflow is not detected or reported by Java's additive operators.

I've created a small application for playing with Java's additive operators. Listing 1 presents its source code.

Listing 1.

class AddOp
   public static void main(String[] args)
      System.out.println(125 + 463);
      System.out.println(2.0 - 6.3);
      int age = 65;
      System.out.println("A" + "B");

In the previous article, we used the JDK's javac tool to compile Java source code and the java tool to run the resulting application. Execute the following command to compile Listing 1:


Assuming successful compilation, you should observe an AddOp.class file in the current directory. Execute the following command to run it:

java AddOp

AddOp responds by producing the following output:


The output provides insight into the postincrement, postdecrement, preincrement, and predecrement operators. For postincrement/postdecrement, age's current value is output before the increment/decrement operation. For preincrement/predecrement, the operation is performed and its result is stored in age, and then age's new value is output.

Postincrement, postdecrement, preincrement, predecrement, and iteration operators

The postincrement, postdecrement, preincrement, and predecrement operators are especially useful in context of an iteration statement, where they are used to advance to the next iteration. I'll introduce iteration statements with these operators in the next Java 101 article.

Array index operator

The array index operator ([]) accesses an array element by providing the element's index (position). This operator is placed after the array variable's name, as in grades[0] (access the first element in the array assigned to grades; the first element is stored at index 0). This operator is formally defined below:

  • Given variable[index], where index must be of integer (int) type, read a value from or store a value into variable's storage element at location index. Example: temperatures[1]

The value passed to index is a 32-bit integer that is either 0 or a positive value ranging to one less than the array's length, which is indicated by appending .length to the name of the array. For example, grades.length returns the number of elements in the array assigned to grades.

Listing 2 presents the source code to an ArrayIndexOp application that lets you play with the array index operator.

Listing 2.

class ArrayIndexOp
   public static void main(String[] args)
      int[] grades = { 89, 90, 68, 73, 79 };
      grades[1] = 91;
      int index = 4;
      System.out.println(grades['C' - 'A']);
//      System.out.println(grades[1D]);

Listing 2 is somewhat more interesting than Listing 1. After creating a five-element, one-dimensional array of integers (via an array initializer) and assigning the array's reference to grades, main() proceeds to access various elements. There are two items of interest:

  • The array index operator's index must ultimately be a 32-bit integer (0 or a positive value). You can specify the name of an integer variable (e.g., index), which contains the index value, as the index.
  • You can specify a calculation involving character literals. When I discuss type conversions later in this article, you will discover why 'C' - 'A' produces an integer (2), which serves as a valid index.

The final example, which passes 1D as an index to the array index operator, is commented out because it will not compile. If you uncomment the line and attempt to compile Listing 2, you will receive an error message about incompatible types: "possible lossy conversion from double to int."

Compile Listing 2 by entering javac, then run the application with the command java ArrayIndexOp. You should observe the following output:


Assignment operators

The assignment operator (=) assigns an expression's value to a variable (e.g., i = 6), including an array element (e.g., x[0] = 15;). The expression and variable must be assignment compatible: their types must agree. For example, you cannot assign a string literal to an integer variable. I'll have more to say about this topic when I discuss type conversions.

The compound assignment operators (+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>=) evaluate expressions and assign the results to variables in one step. Each expression and variable must be assignment compatible. Each operator serves as a useful shortcut. For example, instead of specifying x = x + 3, you can specify the shorter and equivalent x += 3;.

Bitwise operators

The bitwise operators modify the binary values of their operands, which must be of an integer (byte, short, int, or long) or character type. These operators include bitwise AND (&), bitwise complement (~), bitwise exclusive OR (^), and bitwise inclusive OR (|); and are formally defined below:

1 2 3 4 Page 1
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.