The following is a table of the available operators in Painless. Each operator will have further information and examples outside of the table. Many operators will have a promotion table as described by the documentation on promotion [MARK].
Operator  Symbol(s)  Precedence  Associativity 

Precedence 
() 
0 
lefttoright 
Field Access 
. 
1 
lefttoright 
Method Call 
. () 
1 
lefttoright 
Null Safe 
?. 
1 
lefttoright 
Function Call 
() 
1 
lefttoright 
Array Initialization 
[] {} 
1 
lefttoright 
Array Access 
[] 
1 
lefttoright 
Array Length 
. 
1 
lefttoright 
List Initialization 
[] 
1 
lefttoright 
List Access 
[] 
1 
lefttoright 
Map Initialization 
[:] 
1 
lefttoright 
Map Access 
[] 
1 
lefttoright 
Post Increment 
++ 
1 
lefttoright 
Post Decrement 
— 
1 
lefttoright 
Pre Increment 
++ 
2 
righttoleft 
Pre Decrement 
— 
2 
righttoleft 
Unary Positive 
+ 
2 
righttoleft 
Unary Negative 
 
2 
righttoleft 
Boolean Not 
! 
2 
righttoleft 
Bitwise Not 
~ 
2 
righttoleft 
Cast 
() 
3 
righttoleft 
Constructor Call 
new () 
3 
righttoleft 
New Array 
new 
3 
righttoleft 
Multiplication 
* 
4 
lefttoright 
Division 
/ 
4 
lefttoright 
Remainder 
% 
4 
lefttoright 
String Concatenation 
+ 
5 
lefttoright 
Addition 
+ 
5 
lefttoright 
Subtraction 
 
5 
lefttoright 
Left Shift 
<< 
6 
lefttoright 
Right Shift 
>> 
6 
lefttoright 
Unsigned Right Shift 
>>> 
6 
lefttoright 
Greater Than 
> 
7 
lefttoright 
Greater Than Or Equal 
>= 
7 
lefttoright 
Less Than 
< 
7 
lefttoright 
Less Than Or Equal 
⇐ 
7 
lefttoright 
Instance Of 
instanceof 
8 
lefttoright 
Equality Equals 
== 
9 
lefttoright 
Equality Not Equals 
!= 
9 
lefttoright 
Identity Equals 
=== 
9 
lefttoright 
Identity Not Equals 
!== 
9 
lefttoright 
Bitwise And 
& 
10 
lefttoright 
Boolean Xor 
^ 
11 
lefttoright 
Bitwise Xor 
^ 
11 
lefttoright 
Bitwise Or 
 
12 
lefttoright 
Boolean And 
&& 
13 
lefttoright 
Boolean Or 
 
14 
lefttoright 
Conditional 
? : 
15 
righttoleft 
Elvis 
?: 
16 
righttoleft 
Assignment 
= 
17 
righttoleft 
Compound Assignment 
$= 
17 
righttoleft 
You group expressions using the precedence operator to guarantee
the order of evaluation and override existing precedence relationships between operators. The format is an opening parenthesis, one or more expressions, and
a closing parenthesis. For example, (20+1)*2
.
Grammar:
precedence: '(' expression ')';
Examples:
int x = (5+4)*6; // declares the variable int x and sets it to (5+4)*6 // where 5+4 is evaluated first due to the precedence operator int y = 2*(x4); // declares the variable int y and sets it to 2*(x4) // where x4 is evaluated first due to the precedence operator
You use the dot operator .
to access a type’s fields and methods.
You access primitive and reference type members in a reference type using the
dot operator . followed by the id of the member. The accessed member behaves
the same way as the type it represents with one exception: if the reference
type is of type def
, the member is also considered to be of type def
and
resolved at runtime.
Grammar:
field_access: ID '.' ID;
Examples:
FeatureTest ft = new FeatureTest(); // Declare FeatureTest variable ft and // set it to a newly allocated FeatureTest ft.x = 5; // Access int member x from ft and assign // it the literal int value 5 ft.y = ft.x; // Access int member y from ft and assign // it the value of ft member x int value = ft.x + ft.y; // Declare variable value as an int, // add ft members x and y together, // assign the sum to the variable value
You call reference type methods using the dot operator and the method id:
.method_id(arg1,...,argn)
. The parentheses are required even if there are no
arguments.
If the reference type is not type def
, the argument types for the method
can be resolved at compile time. An error occurs if appropriate type
conversions (casting) cannot be performed. If the reference type is type def
, the argument types for the method are all considered to be the type def
. The
appropriate type conversions are performed at runtime.
Automatic boxing and unboxing is performed when you pass in arguments to a method.
Method calls can be overloaded based on arity in Painless. The same method name can be reused for different methods as long as the number of arguments differs. This differs from Java method overloading, where only the types must differ. This has an effect on some of the provided reference type methods in the Painless API. Where there are overloaded methods with the same arity for a reference type in Java, Painless chooses a single method to be provided.
Grammar:
method_call: ID '.' ID '(' (expression (',' expression)*)? ')';
Examples:
Map m = new HashMap(); // Declare Map variable m and set it a newly // allocated HashMap x.put(1, 2); // Call the put method on variable x to add key 1 // with the value 2 to the Map int z = x.get(1); // Declare int variable z, call the get method to // retrieve the value of key 1, and assign the // return value of the method call to variable z def d = new ArrayList(); // Declare def variable m and set it a newly // allocated ArrayList d.add(1); // Call the add method on variable d and add the // literal int 1 to the ArrayList. Note that // the argument type is considered to be of // type def since the reference type is also def int i = Integer.parseInt('2'); // Declare int variable i and set it to the // value returned by the static method parseInt
The null safe operator ?.
can be used in place of the dot operator
to check if a reference type instance is null
before attempting to access
a field or make a method call against it. When using the null safe operator,
if the instance is null
, the returned value is null
. If the reference
type instance is nonnull, it returns the value of the field or result of
the method call normally.
All resultant types must be a reference type or be able to be implicitly cast to a reference type or an error will occur.
Grammar:
null_safe: null_safe_field_access  null_safe_method_call; null_safe_field_access: ID '?.' ID; null_safe_method_call: ID '?.' ID '(' (expression (',' expression)*)? ')';
Examples:
Map x = new HashMap(); // Declare the Map variable x and set it to a newly // allocated HashMap Map y = null; // Declare the Map variable y and set it to null def z = new HashMap(); // Declares the def variable z and set it to a newly // allocated HashMap x.put(1, 2); // Put the keyvalue pair 1 and 2 into x z.put(5, 6); // Put the keyvalue pair 5 and 6 into z def value = x?.get(1); // Declare the def variable value and set it to the // result of .get(1) since x is not null value = y?.get(3); // Sets value to null since y is null value = z?.get(5); // Sets value to the result of .get(5) since z is not null
Userdefined function calls can be made in Painless using the parenthesis operator. See Function Calls [MARK] for more information.
The brackets operator []
is used to create and access arrays, lists, and maps.
The braces operator {}
is used to intialize arrays.
You create and initialize arrays using the brackets []
and braces {}
operators. Each set of brackets represents a dimension. The values you want to
initialize each dimension with are specified as a commaseparated list enclosed
in braces. For example, new int[] {1, 2, 3}
creates a one dimensional int
array with a size of 3 and the values 1, 2, and 3.
For more information about allocating and initializing arrays, see Array Type.
Elements in an array are stored and accessed using the brackets []
operator.
Elements are referenced by an expression enclosed in brackets. An error
occurs if the expression used to reference an element cannot be implicitly
cast to an int
.
The range of elements within an array that can be accessed is [0, size)
where
size is the originally allocated size of the array. To access elements relative
to the last element in an array, you can use a negative numeric value from
[size, 1]
. An error occurs if you attempt to reference an element outside
of the array’s range.
Grammar:
brace_access: '[' expression ']'
Examples:
int[] x = new int[2]; // Declare int array x and set it to a newly allocated // array with a size of 2 x[0] = 2; // Set the 0th element of array x to 2 x[1] = 5; // Set the 1st element of array x to 5 int y = x[0] + x[1]; // Declare the int variable y and set it to the sum // of the first two elements of array x int z = 1; // Declare the int variable z and set it to 1 return x[z]; // Access the 1st element of array x using the // variable z as an expression and return the value def d = new int[2]; // Declare def variable d and set it to a newly // allocated array with a size of 2 d[0] = 2; // Set the 0th element of array d to 2 d[1] = 5; // Set the 1st element of array d to 2 def y = d[0] + d[1]; // Declare def variable y and set it to the sum // of the first two elements of array d def z = 1; // Declare def variable z and set it to 1 return d[z]; // Access the 1st element of array d using the // variable z as an expression and return the value
The use of the def
type in the second example means that the types
cannot be resolved until runtime.
Arrays contain a special member known as length that is a readonly value that contains the size of the array. This member can be accessed from an array using the dot operator.
Examples:
int[] x = new int[10]; // declares an int array variable x and sets it to a newly allocated array with a size of 10 int l = x.length; // declares and int variable l and sets it to the field length of variable x
You create and initialize lists using the brackets []
operator. The values
you want to initialize the list with are specified as a commaseparated list
of expressions enclosed in brackets. For example, List l = [1, 2, 3]
creates
a new three item list. Each expression used to initialize the list is converted
a def
type when the value is inserted into the list. The order of the
expressions is maintained.
Grammar:
list_initialization: '[' expression (',' expression)* ']'  '[' ']';
Examples:
List empty = []; // declares the List variable empty and sets it to a newly initialized empty List List l0 = [1, 2, 3]; // declares the List variable l0 and sets it to a newly initialized List with the values 1, 2, and 3 int i = 1; long l = 2L; float f = 3.0F; double d = 4.0; String s = "5"; List l1 = [i, l, f*d, s]; // declares the List variable l1 and sets it to a newly initialized List with the values of i, l, and f*d and s
Elements in a List are stored or accessed using the brackets operator. The format begins with an opening bracket, followed by an expression, and finishes with a closing bracket. Storing elements in a List is equivalent to invoking a List’s set method. Accessing elements in a List is equivalent to invoking a List’s get method. Using this operator is strictly a shortcut for the previously mentioned methods. The range of elements within a List that can be accessed is [0, size) where size is the number of elements currently in the List. Elements may also be accessed from the last element in a List using a negative numeric value from [size, 1]. The expression used to determine which element is accessed must be able to be implicitly cast to an int. An error will occur if the expression is outside of the legal range or is not of type int.
Grammar:
list_access: '[' expression ']'
Examples:
List x = new ArrayList(); // declares a List variable x and sets it to a newly allocated ArrayList x.add(1); // invokes the add method on the variable x and adds the constant int 1 to the List x.add(2); // invokes the add method on the variable x and adds the constant int 2 to the List x.add(3); // invokes the add method on the variable x and adds the constant int 3 to the List x[0] = 2; // sets the 0th element of the variable x to the constant int 2 x[1] = 5; // sets the 1st element of the variable x to the constant int 2 int y = x[0] + x[1]; // declares the int variable y and sets it to the sum of the first two elements of the variable x int z = 1; // declares the int variable z and sets it to the constant int 1 return x[z]; // accesses the 1st element of the variable x using the variable z as an expression and returns the value def d = new ArrayList(); // declares a def variable d and sets it to a newly allocated ArrayList d.add(1); // invokes the add method on the variable d and adds the constant int 1 to the List d.add(2); // invokes the add method on the variable d and adds the constant int 2 to the List d.add(3); // invokes the add method on the variable d and adds the constant int 3 to the List d[0] = 2; // sets the 0th element of the variable d to the constant int 2 d[1] = 5; // sets the 1st element of the variable d to the constant int 2 def y = d[0] + d[1]; // declares the def variable y and sets it to the sum of the first two elements of the variable d def z = 1; // declares the def variable z and sets it to the constant int 1 return d[z]; // accesses the 1st element of the variable d using the variable z as an expression and returns the value
Note in the first example above all types can be resolved at compiletime, while in the second example all types must wait to be resolved until runtime.
A Map can be created and initialized using the brackets operator. The format begins with a bracket, followed by an arbitrary number of keyvalue pairs delimited with commas (except the last), and ends with a closing bracket. Each keyvalue pair is a set of two expressions separate by a colon. If there is only a single colon with no expressions, a new empty Map is created.
Grammar:
map_initialization: '[' key_pair (',' key_pair)* ']'  '[' ':' ']'; key_pair: expression ':' expression
Each expression used as part of the initialization is converted to a def
type
for insertion into the map.
Examples:
Map empty = [:]; // declares the Map variable empty and sets it to a newly initialized empty Map Map m0 = [1:2, 3:4, 5:6]; // declares the Map variable m0 and sets it to a newly initialized Map with the keys 1, 3, 5 and values 2, 4, 6, respectively byte b = 0; int i = 1; long l = 2L; float f = 3.0F; double d = 4.0; String s = "5"; Map m1 = [b:i, l:f*d, d:s]; // declares the Map variable m1 and sets it to a newly initialized Map with the keys b, l, d and values i, f*d, s, respectively
Elements in a Map can be stored or accessed using the brackets operator. The format begins with an opening bracket, followed by an expression, and finishes with a closing bracket. Storing values in a Map is equivalent to invoking a Map’s put method. Accessing values in a Map is equivalent to invoking a Map’s get method. Using this operator is strictly a shortcut for the previously mentioned methods. Any element from a Map can be stored/accessed where the expression is the key. If a key has no corresponding value when accessing a Map then the value will be null.
Grammar:
map_access: '[' expression ']'
Examples:
Map x = new HashMap(); // declares a Map variable x and sets it to a newly allocated HashMap x['value2'] = 2; // puts the value of the key constant String value2 of the variable x to the constant int 2 x['value5'] = 5; // puts the value of the key constant String value5 of the variable x to the constant int 5 int y = x['value2'] + x['value5']; // declares the int variable y and sets it to the sum of the two values of the variable x String z = 'value5'; // declares the String variable z and sets it to the constant String value5 return x[z]; // accesses the value for the key value5 of the variable x using the variable z as an expression and returns the value def d = new HashMap(); // declares a def variable d and sets it to a newly allocated HashMap d['value2'] = 2; // puts the value of the key constant String value2 of the variable d to the constant int 2 d['value5'] = 5; // puts the value of the key constant String value5 of the variable d to the constant int 5 int y = d['value2'] + d['value5']; // declares the int variable y and sets it to the sum of the two values of the variable d String z = 'value5'; // declares the String variable z and sets it to the constant String value5 return d[z]; // accesses the value for the key value5 of the variable x using the variable z as an expression and returns the value
Note in the first example above all types can be resolved at compiletime, while in the second example all types must wait to be resolved until runtime.
A variable/field representing a numerical value can be possibly evaluated as part of an expression, and then increased by 1 for its respective type. The format starts with a variable name followed by a plus and ends with a plus.
Grammar:
post_increment: ( variable  member ) '++'
A numeric promotion may occur during a postincrement followed by a downcast if necessary. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. A downcast may be required after the type promotion to assign the appropriate value back into the variable/field. Nonnumeric variables/members will result in an error.
Promotion Table:
from 
to 
downcast 
byte 
int 
byte 
short 
int 
short 
char 
int 
char 
int 
int 

long 
long 

float 
float 

double 
double 

def 
def 
Examples(s):
int i = 0; // declares the int variable i and sets it to the constant 0 i++; // increments the int variable i by 1 to a value of 1 long l = 1; // declares the long variable l and set it the constant 1 long k; // declares the long variable k k = l++; // sets the long variable k to the value of l (1), and then increments the long variable l by 1 to a value of 2
A variable/field representing a numerical value can be possibly evaluated as part of an expression, and then increased by 1 for its respective type. The format starts with a variable name followed by a minus and ends with a minus.
Grammar:
post_increment: ( variable  member ) ''
A numeric promotion may occur during a postdecrement followed by a downcast if necessary. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. A downcast may be required after the type promotion to assign the appropriate value back into the variable/field. Nonnumeric variables/members will result in an error.
Promotion Table:
from 
to 
downcast 
byte 
int 
byte 
short 
int 
short 
char 
int 
char 
int 
int 

long 
long 

float 
float 

double 
double 

def 
def 
Examples(s):
short i = 0; // declares the short variable i and sets it to the constant short 0 i; // decrements the short variable i by 1 to a value of 1 (promoted to int and downcast to short) float l = 1.0f; // declares the float variable l and sets it the constant float 1.0f float k; // declares the float variable k k = l; // sets the float variable k to the value of l (1.0f), and then decrements the float variable l by 1.0 to a value of 0.0
A variable/field representing a numerical value can be increased by 1 for its respective type, and then possibly evaluated as part of an expression. The format starts with a plus followed by a plus and ends with a variable name.
Grammar:
pre_increment: '++' ( variable  member )
A numeric promotion may occur during a preincrement followed by a downcast if necessary. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. A downcast may be required after the type promotion to assign the appropriate value back into the variable/field. Nonnumeric variables/members will result in an error.
Promotion Table:
from 
to 
downcast 
byte 
int 
byte 
short 
int 
short 
char 
int 
char 
int 
int 

long 
long 

float 
float 

double 
double 

def 
def 
Examples(s):
int i = 0; // declares the int variable i and sets it to the constant int 0 ++i; // increments the int variable i by 1 to a value of 1 long l = 1; // declares the long variable l and sets it to the constant long 1 long k; // declares the long variable k k = ++l; // increments the long variable l by 1 to a value of 2, and then sets the long variable k to the value of l (2)
A variable/field representing a numerical value can be decreased by 1 for its respective type, and then possibly evaluated as part of an expression. The format starts with a minus followed by a minus and ends with a variable name.
Grammar:
pre_decrement: '' ( variable  member )
A numeric promotion may occur during a predecrement followed by a downcast if necessary. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. A downcast may be required after the type promotion to assign the appropriate value back into the variable/field. Nonnumeric variables/members will result in an error.
Promotion Table:
from 
to 
downcast 
byte 
int 
byte 
short 
int 
short 
char 
int 
char 
int 
int 

long 
long 

float 
float 

double 
double 

def 
def 
Examples(s):
byte i = 1; // declares the byte variable i and sets it to the constant int 1 i; // decrements the byte variable i by 1 to a value of 0 (promoted to int and downcast to byte) double l = 1.0; // declares the double variable l and sets it to the constant double 1.0 double k; // declares the double variable k k = l; // decrements the double variable l by 1.0 to a value of 0.0, and then sets the double variable k to the value of l (0.0)
Unary positive gives the identity of a numerical value using the plus operator. In practice this is usually a noop, but will cause some numeric types to be promoted. Format starts with a plus operator followed by a numerical expression.
Grammar:
unary_positive: '+' expression
A numeric promotion may occur during a unary positive operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
from 
to 
byte 
int 
short 
int 
char 
int 
int 
int 
long 
long 
float 
float 
double 
double 
def 
def 
Examples:
int x = +1; // declares the int variable x and sets it to positive 1 long y = +x; // declares the long variable y and sets it to positive x (promoted to long from int) def z = +y; // declares the def variable z and sets it to positive y byte z = +2; //ERROR: cannot implicitly downcast an int to a byte
Unary negative negates a numeric value using the minus operator. Format starts with a minus followed by a numerical expression.
Grammar:
unary_negative: '' expression
A numeric promotion may occur during a unary negative operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
from 
to 
byte 
int 
short 
int 
char 
int 
int 
int 
long 
long 
float 
float 
double 
double 
def 
def 
Examples:
int x = 1; // declares the int variable x and sets it to negative 1 long y = x; // declares the long variable y and sets it to negative x (promoted to long from int) def z = y; // declares the def variable z and sets it to negative y byte z = 2; //ERROR: cannot implicitly downcast an int to a byte
Boolean not will flip a boolean value from true to false or false to true using the bang operator. The format is a bang operator followed by an expression.
Grammar:
boolean_not: '!' expression;
Note that def types will be assumed to be of the boolean type. Any def type evaluated at runtime that does not represent a boolean will result in an error. Nonboolean expressions will result in an error.
Examples:
boolean x = !false; // declares the boolean variable x and sets it to the the opposite of the false value boolean y = !x; // declares the boolean variable y and sets it to the opposite of the boolean variable x def z = !y; // declares the def variable z and sets it to the opposite of the boolean variable y
Bitwise not will flip each bit of an integer type expression. The format is the tilde operator followed by an expression.
Grammar:
bitwise_not: '~' expression;
A numeric promotion may occur during unary positive operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Noninteger expressions will result in an error.
Promotion Table:
from 
to 
byte 
int 
short 
int 
char 
int 
int 
int 
long 
long 
def 
def 
Examples:
byte x = 1; // declares the byte variable x and sets it to a constant int 1 int y = ~x; // declares the int variable y and sets it to the negation of x long z = ~y; // declares the long variable z and sets it the negation of y def d = ~z; // declares the def variable d and sets it the negation of z def e; // declares the def variable e e = ~d; // sets e the negation of d
The cast operator can be used to explicitly convert one type to another. See casting [MARK] for more information.
A constructor call is a special type of method call [MARK] used to allocate a reference type instance using the new operator. The format is the new operator followed by a type, an opening parenthesis, arguments if any, and a closing parenthesis. Arguments are a series of zerotomany expressions delimited by commas. Autoboxing and autounboxing will be applied automatically for arguments passed into a constructor call. See boxing and unboxing [MARK] for more information on this topic. Constructor argument types can always be resolved at runtime; if appropriate type conversions (casting) cannot be applied an error will occur. Once a reference type instance has been allocated, its members may be used as part of other expressions.
Constructor calls may be overloaded based on arity in Painless. This means the same reference type may have multiple constructors as long as the number of arguments differs for each one. This does have an effect on some of the provided reference type constructors in the Painless API [MARK]. When there are overloaded constructors with the same arity for a reference type in Java a single constructor must be chosen to be provided in Painless.
Grammar:
constructor_call: 'new' TYPE '(' (expression (',' expression)*)? ')';
Examples:
Map m = new HashMap(); // declares the Map variable m and sets it to a newly allocated HashMap using an empty constructor m.put(3, 3); // invokes the method call member put and adds the keyvalue pair of 3 to Map variable m def d = new ArrayList(); // declares the def variable d and sets it to a newly allocated ArrayList using an empty constructor def e; // declares the def variable e e = new HashMap(m); // sets e to a newly allocated HashMap using the constructor with a single argument m
An array type instance can be allocated using the new operator. The format starts with the new operator followed by the type followed by a series of opening and closing braces each containing an expression for the size of the dimension.
Grammar:
new_array: 'new' TYPE ('[' expression ']')+;
Examples:
int[] x = new int[5]; // declares an int array variable x and sets it to a newly allocated array with a size of 5 x = new int[10]; // sets the int array variable x to a newly allocated array with a size of 10 def[][] y = new def[5][5]; // declares a 2dimensional def array variable y and set it to a newly // allocated 2dimensional array where both dimensions have a size of 5
Multiplies two numerical expressions. Rules for resultant overflow and NaN values follow the Java specification. The format is an expression, followed by the star operator, and a closing expression.
Grammar:
multiplication: expression '*' expression;
A numeric promotion may occur during a multiplication operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric numbers will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
int x = 5*4; // declares the int variable x and sets it to the result of 5 multiplied by 4 double y = x*7.0; // declares the double variable y and sets it to the result of x multiplied by 7.0 (x is promoted to a double) def z = x*y; // declares the def variable z and sets it to the result of x multiplied by y (x is promoted to a double) def a = z*x; // declares the def variable a and sets it to the result of z multiplied by x (x is promoted to def at compiletime and double at runtime)
Divides two numerical expressions. Rules for NaN values and division by zero follow the Java specification. Integer division will drop the remainder of the resultant value. The format is an expression, followed by the slash operator, and a closing expression.
Grammar:
division: expression '/' expression;
A numeric promotion may occur during a division operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
int x = 5/4; // declares the int variable x and sets it to the result of 5 divided by 4 double y = x/7.0; // declares the double variable y and sets it to the result of x divided by 7.0 (x is promoted to a double) def z = x/y; // declares the def variable z and sets it to the result of x divided by y (x is promoted to a double) def a = z/x; // declares the def variable a and sets it to the result of z divided by x (x is promoted to def at compiletime and double at runtime)
Calculates the remainder for division between two numerical expressions. Rules for NaN values and division by zero follow the Java specification. The format is an expression, followed by the percent operator, and a closing expression.
Grammar:
remainder: expression '%' expression;
A numeric promotion may occur during a remainder operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
int x = 5%4; // declares the int variable x and sets it to the remainder of 5 divided by 4 double y = x%7.0; // declares the double variable y and sets it to the remainder of x divided by 7.0 (x is promoted to a double) def z = x%y; // declares the def variable z and sets it to the remainder of x divided by y (x is promoted to a double) def a = z%x; // declares the def variable a and sets it to the remainder of z divided by x (x is promoted to def at compiletime and double at runtime)
Concatenates two expressions together as a single String where at least of one of the expressions is a String to begin with. The format is an expression, followed by a plus operator, and a closing expression.
Grammar:
concatenate: expression '+' expression;
Examples:
String x = "con"; // declares the String variable x and sets it to the String constant "con" String y = x + "cat"; // declares the String variable y and sets it to the concatenation of the String variable x and the String constant "cat" String z = 4 + x; // declares the String variable z and sets it to the concatenation of the int constant 4 and the String variable x (4 is implicitly cast to a String) def d = 2; // declares the def variable d and sets it to the int constant 2 z = z + d; // sets the String variable z to the concatenation of the String variable z d = "con" + x + y + "cat"; // sets the def variable d to the concatenation of String constant "con", x, y, and the String constant "cat"
Adds two numerical expressions. Rules for resultant overflow and NaN values follow the Java specification. The format is an expression, followed by the plus operator, and a closing expression.
Grammar:
addition: expression '+' expression;
A numeric promotion may occur during a addition operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error, except in the case of String which then implies the operation is string concatenation [MARK] rather than addition.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
int x = 5 + 4; // declares the int variable x and sets it to the result of 5 added to 4 double y = x + 7.0; // declares the double variable y and sets it to the result of x added to 7.0 (x is promoted to a double) def z = x + y; // declares the def variable z and sets it to the result of x added to y (x is promoted to a double) def a = z + x; // declares the def variable a and sets it to the result of z added to x (x is promoted to def at compiletime and double at runtime)
Subtracts two numerical expressions. Rules for resultant overflow and NaN values follow the Java specification. The format is an expression, followed by the minus operator, and a closing expression.
Grammar:
subtraction: expression '' expression;
A numeric promotion may occur during a subtraction operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
int x = 54; // declares the int variable x and sets it to the result of 4 subtracted from 5 double y = x7.0; // declares the double variable y and sets it to the result of 7.0 subtracted from x (x is promoted to a double) def z = xy; // declares the def variable z and sets it to the result of y subtracted from x (x is promoted to a double) def a = zx; // declares the def variable a and sets it to the result of x subtracted from z (x is promoted to def at compiletime and double at runtime)
Shifts lower order bits to higher order bits in the leftside expression by the distance specified in the rightside expression. The format is an expression followed by two leftcarrots, and a closing expression.
Grammar:
left_shift: expression '<<' expression;
A numeric promotion may occur during a left shift operation to the leftside expression. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric and floating point expressions will result in an error.
Promotion Table:
from 
to 
byte 
int 
short 
int 
char 
int 
int 
int 
long 
long 
def 
def 
The rightside expression will be explicitly cast to an int value and truncated based on the promoted type of the leftside expression. If the leftside expression is of type int then the lowest order 5bits will be taken as the distance to shift from the rightside expression (031). If the leftside expression is of type long then the lowest order 6bits will be taken as the distance to shift from the rightside expression (063). Nonnumeric and floating point expressions will result in an error.
Examples:
int x = 5 << 4; // declares the int variable x and sets it to the result of 5 left shifted by 4 long y = x << 7; // declares the long variable y and sets it to the result of x left shifted by 7 (x is promoted to a long) def z = x << y; // declares the def variable z and sets it to the result of x left shifted by y def a = z << x; // declares the def variable a and sets it to the result of z left shifted by x
Shifts higher order bits to lower order bits in the leftside expression by the distance specified in the rightside expression. Right shift will preserve the signed bit (highest order bit) as part of the result. The format is an expression followed by two rightcarrots, and a closing expression.
Grammar:
right_shift: expression '>>' expression;
A numeric promotion may occur during a right shift operation to the leftside expression. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric and floating point expressions will result in an error.
Promotion Table:
from 
to 
byte 
int 
short 
int 
char 
int 
int 
int 
long 
long 
def 
def 
The rightside expression will be explicitly cast to an int value and truncated based on the promoted type of the leftside expression. If the leftside expression is of type int then the lowest order 5bits will be taken as the distance to shift from the rightside expression (031). If the leftside expression is of type long then the lowest order 6bits will be taken as the distance to shift from the rightside expression (063). Nonnumeric and floating point expressions will result in an error.
Examples:
int x = 5 >> 4; // declares the int variable x and sets it to the result of 5 right shifted by 4 long y = x >> 7; // declares the long variable y and sets it to the result of x right shifted by 7 (x is promoted to a long) def z = x >> y; // declares the def variable z and sets it to the result of x right shifted by y def a = z >> x; // declares the def variable a and sets it to the result of z right shifted by x
Shifts higher order bits to lower order bits in the leftside expression by the distance specified in the rightside expression. Unsigned right shift will not preserve the signed bit (highest order bit) as part of the result. The format is an expression followed by three rightcarrots, and a closing expression.
Grammar:
unsigned_right_shift: expression '>>>' expression;
A numeric promotion may occur during an unsigned right shift operation to the leftside expression. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric and floating point expressions will result in an error.
Promotion Table:
from 
to 
byte 
int 
short 
int 
char 
int 
int 
int 
long 
long 
def 
def 
The rightside expression will be explicitly cast to an int value and truncated based on the promoted type of the leftside expression. If the leftside expression is of type int then the lowest order 5bits will be taken as the distance to shift from the rightside expression (031). If the leftside expression is of type long then the lowest order 6bits will be taken as the distance to shift from the rightside expression (063). Nonnumeric and floating point expressions will result in an error.
Examples:
int x = 5 >> 4; // declares the int variable x and sets it to the result of 5 unsigned right shifted by 4 long y = x >> 7; // declares the long variable y and sets it to the result of x unsigned right shifted by 7 (x is promoted to a long) def z = x >> y; // declares the def variable z and sets it to the result of x unsigned right shifted by y def a = z >> x; // declares the def variable a and sets it to the result of z unsigned right shifted by x
Greater than compares two numerical expressions where a resultant boolean value will be true if the leftside expression is a larger value than the rightside expression otherwise false. The format is an expression, followed by the right angle operator, and a closing expression.
Grammar:
greater_than: expression '>' expression;
A numeric promotion may occur during a greater than operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean x = 5 > 4; // declares the int variable x and sets it to the result of 5 greater than 4 double y = 7.0; // declares the double variable y and sets it to the double constant 7.0 def z = y > 6.5; // declares the def variable z and sets it to the result of y greater than 6.5 def a = y > x; // declares the def variable a and sets it to the result of y greater than z (x is promoted to double at compiletime)
Greater than or equal compares two numerical expressions where a resultant boolean value will be true if the leftside expression is a larger value than or equal to the rightside expression otherwise false. The format is an expression, followed by the right angle and equals operator, and a closing expression.
Grammar:
greater_than_or_equal: expression '>=' expression;
A numeric promotion may occur during a greater than or equal operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean x = 5 >= 4; // declares the int variable x and sets it to the result of 5 greater than or equal to 4 double y = 7.0; // declares the double variable y and sets it to the double constant 7.0 def z = y >= 6.5; // declares the def variable z and sets it to the result of y greater than or equal to 6.5 def a = y >= x; // declares the def variable a and sets it to the result of y greater than or equal to z (x is promoted to double at compiletime)
Less than compares two numerical expressions where a resultant boolean value will be true if the leftside expression is a smaller value than the rightside expression otherwise false. The format is an expression, followed by the left angle operator, and a closing expression.
Grammar:
less_than: expression '<' expression;
A numeric promotion may occur during a less than operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean x = 5 < 4; // declares the int variable x and sets it to the result of 5 less than 4 double y = 7.0; // declares the double variable y and sets it to the double constant 7.0 def z = y < 6.5; // declares the def variable z and sets it to the result of y less than 6.5 def a = y < x; // declares the def variable a and sets it to the result of y less than z (x is promoted to double at compiletime)
Less than or equal compares two numerical expressions where a resultant boolean value will be true if the leftside expression is a larger value than or equal to the rightside expression otherwise false. The format is an expression, followed by the left angle and equals operator, and a closing expression.
Grammar:
less_than_or_equal: expression '<=' expression;
A numeric promotion may occur during a less than or equal operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Nonnumeric expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean x = 5 <= 4; // declares the int variable x and sets it to the result of 5 less than or equal to 4 double y = 7.0; // declares the double variable y and sets it to the double constant 7.0 def z = y <= 6.5; // declares the def variable z and sets it to the result of y less than or equal to 6.5 def a = y <= x; // declares the def variable a and sets it to the result of y less than or equal to z (x is promoted to double at compiletime)
The instanceof operator can be used to compare a variable’s type to a specified reference type where a resultant boolean value is true if the variable type is the same as or a descendant of the specified reference type and false otherwise. The format is an id, followed by the instanceof operator, and finished with a type.
Grammar:
instance_of: ID 'instanceof' TYPE;
Examples:
Map x = new HashMap(); // declares the Map variable x and sets it to a newly allocated HashMap List y = new ArrayList(); // declares the List variable y and sets it to a newly allocated ArrayList def z = y; // declares the def variable z and sets it to y boolean a = x instanceof HashMap; // declares the boolean variable a and sets it to true since x's type is the same type as HashMap boolean b = y instanceof Map; // declares the boolean variable b and sets it to false since y's type is not the same type as Map or a descendant of Map boolean c = z instanceof List; // declares the boolean variable c and sets it to true since z's type is a descendant of the type List
Equality equals compares two expressions where a resultant boolean value is true if the two expressions are equal and false otherwise. When reference types are compared using this operator the equivalent of the equals member method will be called against the first expression, where the second expression is the argument. Though the equals member method is used for reference types, this operation will always be nullsafe. Valid comparisons are between boolean types, primitive numeric types, and reference types. If a comparison is made that is not listed as one of the valid comparisons an error will occur. The format is an expression, followed by the equalsequals operator, and finished with an expression.
Grammar:
equality_equals: expression '==' expression;
A numeric type promotion may occur during a primitive numeric comparison. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean b0 = true; // declares the boolean variable b0 and sets it the constant boolean true boolean b1 = false; // declares the boolean variable b1 and sets it the constant boolean false int i = 2; // declares the int variable i and sets it the constant int 2 float f = 2.0f; // declares the float variable f and sets it the constant float 2.0 List l0 = new ArrayList(); // declares the List variable l0 and sets it to a newly allocated ArrayList ArrayList l1 = new ArrayList(); // declares the ArrayList variable l1 and sets it to a newly allocated ArrayList def di0 = 2; // declares the def variable di0 and sets it the constant int 2 def di1 = 3; // declares the def variable di1 and sets it the constant int 3 def dl = new ArrayList(); // declares the def variable dl and sets it to a newly allocated ArrayList boolean result; // declares the boolean variable result result = b0 == b1; // compares b0 to b1 and has a boolean result of false result = i == f; // compares i to f where i is promoted to float and has a boolean result of true result = b0 == i; // ERROR: a comparison between a boolean and a primitive numeric type is illegal result = i == l0; // ERROR: a comparison between a primitive numeric type and a reference type is illegal l0.add(1); // adds a constant int 1 to the List l0 l1.add(1); // adds a constant int 1 to the ArrayList l1 result = l0 == l1; // compares l0 to l1 using l0.equals(l1) and has a boolean result of true l0.add(1); // adds a constant int 1 to the List l0 result = l0 == l1; // compares l0 to l1 using l0.equals(l1) and has a boolean result of false result = di0 == di1; // compares di0 to di1 and has a boolean result of false result = di0 == i; // compares di0 to i where i is promoted to def and has a boolean result of true dl.add(1); // adds a constant int 1 to the def ArrayList dl result = dl == l0; // compares dl to l0 using dl.equals(l0) with a boolean result of true result = null == dl; // compares null to dl with a boolean result of false result = l1 == null; // compares l1 to null with a boolean result of false
Equality not equals compares two expressions where a resultant boolean value is true if the two expressions are not equal and false otherwise. When reference types are compared using this operator the equivalent of the equals member method will be called against the first expression, where the second expression is the argument, with the resultant boolean being reversed. Though the equals member method is used for reference types, this operation will always be nullsafe. Valid comparisons are between boolean types, primitive numeric types, and reference types. If a comparison is made that is not listed as one of the valid comparisons an error will occur. The format is an expression, followed by the bangequals operator, and finished with an expression.
Grammar:
equality_not_equals: expression '!=' expression;
A numeric type promotion may occur during a primitive numeric comparison. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean b0 = true; // declares the boolean variable b0 and sets it the constant boolean true boolean b1 = false; // declares the boolean variable b1 and sets it the constant boolean false int i = 2; // declares the int variable i and sets it the constant int 2 float f = 2.0f; // declares the float variable f and sets it the constant float 2.0 List l0 = new ArrayList(); // declares the List variable l0 and sets it to a newly allocated ArrayList ArrayList l1 = new ArrayList(); // declares the ArrayList variable l1 and sets it to a newly allocated ArrayList def di0 = 2; // declares the def variable di0 and sets it the constant int 2 def di1 = 3; // declares the def variable di1 and sets it the constant int 3 def dl = new ArrayList(); // declares the def variable dl and sets it to a newly allocated ArrayList boolean result; // declares the boolean variable result result = b0 != b1; // compares b0 to b1 and has a boolean result of true result = i != f; // compares i to f where i is promoted to float and has a boolean result of false result = b0 != i; // ERROR: a comparison between a boolean and a primitive numeric type is illegal result = i != l0; // ERROR: a comparison between a primitive numeric type and a reference type is illegal l0.add(1); // adds a constant int 1 to the List l0 l1.add(1); // adds a constant int 1 to the ArrayList l1 result = l0 != l1; // compares l0 to l1 using l0.equals(l1) and has a boolean result of false l0.add(1); // adds a constant int 1 to the List l0 result = l0 != l1; // compares l0 to l1 using l0.equals(l1) and has a boolean result of true result = di0 != di1; // compares di0 to di1 and has a boolean result of true result = di0 != i; // compares di0 to i where i is promoted to def and has a boolean result of false dl.add(1); // adds a constant int 1 to the def ArrayList dl result = dl != l0; // compares dl to l0 using dl.equals(l0) with a boolean result of false result = null != dl; // compares null to dl with a boolean result of true result = l1 != null; // compares null to l1 with a boolean result of true
Identity equals compares two expressions where a resultant boolean value is true if the two expressions are equal and false otherwise. Two primitive types are considered to be equal if they have the same value. Two reference types are considered to be equal if they refer to the exact same instance in memory or are both null. Valid comparisons are between boolean types, primitive numeric types, and reference types. If a comparison is made that is not listed as one of the valid comparisons an error will occur. The format is an expression, followed by the equalsequalsequals operator, and finished with an expression.
Grammar:
identity_equals: expression '===' expression;
A numeric type promotion may occur during a primitive numeric comparison. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean b0 = true; // declares the boolean variable b0 and sets it the constant boolean true boolean b1 = false; // declares the boolean variable b1 and sets it the constant boolean false int i = 2; // declares the int variable i and sets it the constant int 2 float f = 2.0f; // declares the float variable f and sets it the constant float 2.0 List l0 = new ArrayList(); // declares the List variable l0 and sets it to a newly allocated ArrayList ArrayList l1 = new ArrayList(); // declares the ArrayList variable l1 and sets it to a newly allocated ArrayList List l2 = l1; // declares the List variable l2 and sets it to l1 def di0 = 2; // declares the def variable di0 and sets it the constant int 2 def di1 = 3; // declares the def variable di1 and sets it the constant int 3 def dl = l0; // declares the def variable dl and sets it to l0 boolean result; // declares the boolean variable result result = b0 === b1; // compares b0 to b1 and has a boolean result of false result = i === f; // compares i to f where i is promoted to float and has a boolean result of true result = b0 === i; // ERROR: a comparison between a boolean and a primitive numeric type is illegal result = i === l0; // ERROR: a comparison between a primitive numeric type and a reference type is illegal l0.add(1); // adds a constant int 1 to the List l0 l1.add(1); // adds a constant int 1 to the ArrayList l1 result = l0 === l1; // compares l0 to l1 and has a boolean result of false l0.add(1); // adds a constant int 1 to the List l0 result = l0 === l1; // compares l0 to l1 and has a boolean result of false result = l1 === l2; // compares l1 to l2 and has a boolean result of true result = di0 === di1; // compares di0 to di1 and has a boolean result of false result = di0 === i; // compares di0 to i where i is promoted to def and has a boolean result of true result = dl === l0; // compares dl to l0 with a boolean result of true result = null === dl; // compares null to dl with a boolean result of false result = l1 === null; // compares null to l1 with a boolean result of false
Identity not equals compares two expressions where a resultant boolean value is true if the two expressions are not equal and false otherwise. Two primitive types are considered to be not equal if they have different values. Two reference types are considered to be not equal if they refer to the different instances in memory or one is null and the other is not. Valid comparisons are between boolean types, primitive numeric types, and reference types. If a comparison is made that is not listed as one of the valid comparisons an error will occur. The format is an expression, followed by the bangequalsequals operator, and finished with an expression.
Grammar:
identity_not_equals: expression '!==' expression;
A numeric type promotion may occur during a primitive numeric comparison. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean b0 = true; // declares the boolean variable b0 and sets it the constant boolean true boolean b1 = false; // declares the boolean variable b1 and sets it the constant boolean false int i = 2; // declares the int variable i and sets it the constant int 2 float f = 2.0f; // declares the float variable f and sets it the constant float 2.0 List l0 = new ArrayList(); // declares the List variable l0 and sets it to a newly allocated ArrayList ArrayList l1 = new ArrayList(); // declares the ArrayList variable l1 and sets it to a newly allocated ArrayList List l2 = l1; // declares the List variable l2 and sets it to l1 def di0 = 2; // declares the def variable di0 and sets it the constant int 2 def di1 = 3; // declares the def variable di1 and sets it the constant int 3 def dl = l0; // declares the def variable dl and sets it to l0 boolean result; // declares the boolean variable result result = b0 !== b1; // compares b0 to b1 and has a boolean result of true result = i !== f; // compares i to f where i is promoted to float and has a boolean result of false result = b0 !== i; // ERROR: a comparison between a boolean and a primitive numeric type is illegal result = i !== l0; // ERROR: a comparison between a primitive numeric type and a reference type is illegal l0.add(1); // adds a constant int 1 to the List l0 l1.add(1); // adds a constant int 1 to the ArrayList l1 result = l0 !== l1; // compares l0 to l1 and has a boolean result of true l0.add(1); // adds a constant int 1 to the List l0 result = l0 !== l1; // compares l0 to l1 and has a boolean result of true result = l1 !== l2; // compares l1 to l2 and has a boolean result of false result = di0 !== di1; // compares di0 to di1 and has a boolean result of true result = di0 !== i; // compares di0 to i where i is promoted to def and has a boolean result of false result = dl !== l0; // compares dl to l0 with a boolean result of false result = null !== dl; // compares null to dl with a boolean result of true result = l1 !== null; // compares null to l1 with a boolean result of true
Bitwise and will and together two integer type expressions. The table below shows what each resultant bit will in the resultant integer type value be based on the corresponding bit in each integer type expression.
1 
0 

1 
1 
0 
0 
0 
0 
The format starts with an expression, follows with the ampersand operator, and finishes with an expression.
Grammar:
bitwise_and: expression '&' expression;
A numeric promotion may occur during a bitwise and operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Noninteger expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
def 

byte 
int 
int 
int 
int 
long 
def 
short 
int 
int 
int 
int 
long 
def 
char 
int 
int 
int 
int 
long 
def 
int 
int 
int 
int 
int 
long 
def 
long 
long 
long 
long 
long 
long 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
byte x = 16; // declares the byte variable x and sets it to a constant int 1 int y = x & 4; // declares the int variable y and sets it to the result of x and 4 long z = y & x; // declares the long variable z and sets it the result of y and x def d = z & 2; // declares the def variable d and sets it the result of z and 2 def e; // declares the def variable e e = d & z; // sets e to the result of d and z
Boolean xor will xor together two boolean expressions. The table below shows what the resultant boolean value will be based on the two boolean expressions.
true 
false 

true 
false 
true 
false 
true 
false 
The format starts with an expression, follows with the carrot operator, and finishes with an expression.
Grammar:
boolean_xor: expression '^' expression;
Note that def types will be assumed to be of the boolean type. Any def type evaluated at runtime that does not represent a boolean will result in an error. Nonboolean expressions will result in an error.
Examples:
boolean x = false; // declares the boolean variable x and sets the constant boolean false boolean y = x ^ true; // declares the boolean variable y and sets it the result of x xor true def z = y ^ x; // declares the def variable z and sets it to the result of y xor x
Bitwise xor will xor together two integer type expressions. The table below shows what each resultant bit will in the resultant integer type value be based on the corresponding bit in each integer type expression.
1 
0 

1 
0 
1 
0 
1 
0 
The format starts with an expression, follows with the carrot operator, and finishes with an expression.
Grammar:
bitwise_xor: expression '^' expression;
A numeric promotion may occur during a bitwise xor operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Noninteger expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
def 

byte 
int 
int 
int 
int 
long 
def 
short 
int 
int 
int 
int 
long 
def 
char 
int 
int 
int 
int 
long 
def 
int 
int 
int 
int 
int 
long 
def 
long 
long 
long 
long 
long 
long 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
byte x = 16; // declares the byte variable x and sets it to a constant int 1 int y = x ^ 4; // declares the int variable y and sets it to the result of x xor 4 long z = y ^ x; // declares the long variable z and sets it the result of y xor x def d = z ^ 2; // declares the def variable d and sets it the result of z xor 2 def e; // declares the def variable e e = d ^ z; // sets e to the result of d xor z
Bitwise or will or together two integer type expressions. The table below shows what each resultant bit will in the resultant integer type value be based on the corresponding bit in each integer type expression.
1 
0 

1 
1 
1 
0 
1 
0 
The format starts with an expression, follows with the pipe operator, and finishes with an expression.
Grammar:
bitwise_or: expression '' expression;
A numeric promotion may occur during a bitwise xor operation. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents. Noninteger expressions will result in an error.
Promotion Table:
byte 
short 
char 
int 
long 
def 

byte 
int 
int 
int 
int 
long 
def 
short 
int 
int 
int 
int 
long 
def 
char 
int 
int 
int 
int 
long 
def 
int 
int 
int 
int 
int 
long 
def 
long 
long 
long 
long 
long 
long 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
byte x = 16; // declares the byte variable x and sets it to a constant int 1 int y = x  4; // declares the int variable y and sets it to the result of x or 4 long z = y  x; // declares the long variable z and sets it the result of y or x def d = z  2; // declares the def variable d and sets it the result of z or 2 def e; // declares the def variable e e = d  z; // sets e to the result of d or z
Boolean and will and together two boolean expressions. If the first expression is found to be false then it is known that the result will also be false, so evaluation of the second expression will be skipped. The table below shows what the resultant boolean value will be based on the two boolean expressions.
truefalse truetruefalse falsefalsefalse
The format starts with an expression, follows with the ampersandampersand operator, and finishes with an expression.
Grammar:
boolean_and: expression '&&' expression;
Note that def types will be assumed to be of the boolean type. Any def type evaluated at runtime that does not represent a boolean will result in an error. Nonboolean expressions will result in an error.
Examples:
boolean x = false; // declares the boolean variable x and sets the constant boolean false boolean y = x && true; // declares the boolean variable y and sets it the result of x and true def z = y && x; // declares the def variable z and sets it to the result of y and x
Boolean or will or together two boolean expressions. If the first expression is found to be true then it is known that the result will also be true, so evaluation of the second expression will be skipped. The table below shows what the resultant boolean value will be based on the two boolean expressions.
true 
false 

true 
true 
true 
false 
true 
false 
The format starts with an expression, follows with the pipepipe operator, and finishes with an expression.
Grammar:
boolean_and: expression '' expression;
Note that def types will be assumed to be of the boolean type. Any def type evaluated at runtime that does not represent a boolean will result in an error. Nonboolean expressions will result in an error.
Examples:
boolean x = false; // declares the boolean variable x and sets the constant boolean false boolean y = x  true; // declares the boolean variable y and sets it the result of x or true def z = y  x; // declares the def variable z and sets it to the result of y or x
A conditional operation consists of three expressions. The first expression is evaluated with an expected boolean result type. If the first expression evaluates to true then the second expression will be evaluated. If the first expression evaluates to false then the third expression will be evaluated. This can be used as a shortcut many different operations without requiring a full if/else branch. Errors will occur if the first expression does not evaluate to a boolean type or if one of the second or third expression cannot be converted to a type appropriate for the expected result. The format is an expression followed by a questionmark operator, another expression, a colon operator, and finishes with a final expression.
Grammar:
conditional: expression '?' expression ':' expression;
A numeric type promotion may occur during the evaluation of a conditional with the second and third expressions if the expected result is a numeric type. A def type evaluated at runtime will follow the same promotion table at runtime following whatever type def represents.
Promotion Table:
byte 
short 
char 
int 
long 
float 
double 
def 

byte 
int 
int 
int 
int 
long 
float 
double 
def 
short 
int 
int 
int 
int 
long 
float 
double 
def 
char 
int 
int 
int 
int 
long 
float 
double 
def 
int 
int 
int 
int 
int 
long 
float 
double 
def 
long 
long 
long 
long 
long 
long 
float 
double 
def 
float 
float 
float 
float 
float 
float 
float 
double 
def 
double 
double 
double 
double 
double 
double 
double 
double 
def 
def 
def 
def 
def 
def 
def 
def 
def 
def 
Examples:
boolean b = true; // declares the boolean variable b and sets it the constant boolean true int x = b ? 1 : 2; // declares the int variable x and sets it to the int constant 1 // since the first expression of the conditional evaluates to true // so the second expression is evaluated for a result List y = x > 1 ? new ArrayList() : null; // declares the List variable y and sets it to null // since the first expression of the conditional evaluates to false // so the third expression is evaluated for a result def z = x < 2 ? true : false; // declares the def variable z and sets it to the boolean constant true // since the first expression of the conditional evaluates to true // so the second expression is evaluated for a result
The elvis operator consists of two expressions. If the first expression is a nonnull value then the resultant value will be the evaluated first expression otherwise the resultant value will be the evaluated second expression. This is typically used as a shortcut for a null check in a conditional. An error will occur if the expected result is a primitive type. The format is an expression, followed by the questionmarkcolon operator, and finishes with an expression.
Grammar:
elvis: expression '?:' expression;
Examples:
List l = new ArrayList(); // declares the List variable l and sets it to a newly allocated ArrayList List y = l ?: new ArrayList(); // declares the List variable y and sets it to l since l is not null y = null; // sets y to null def z = y ?: new HashMap(); // declares the def variable z and sets it to a newly allocated HashMap since y is null
Assignment can be used to assign a value to a variable. See Variable Assignment [MARK] for more information.
Compound assignment can be used as a shortcut for an assignment where a binary operation would occur between the variable/field as the leftside expression and a separate rightside expression. The variable/field and rightside expression must be of appropriate types for the specific operation or an error will occur. A downcast may be necessary for certain operations to be able to assign the result back into the variable/field and will happen implicitly. The format is a variable/field, followed by one of the compound assignment operators, finished with an expression.
Grammar:
compund_assignment: ID (. ID)? '$=' expression; // $ is a placeholder for the operation symbol
A compound assignment is equivalent to the expression below where V is the variable/field and T is the type of variable/member.
V = (T)(V op expression);
The table below shows all available operators for compound assignment. All operators follow any casting/promotion rules according to their regular definition.
Operator 
Compound Symbol 
Multiplication 
*= 
Division 
/= 
Remainder 
%= 
String Concatenation 
+= 
Addition 
+= 
Subtraction 
= 
Left Shift 
<⇐ 
Right Shift 
>>= 
Unsigned Right Shift 
>>>= 
Bitwise And 
&= 
Boolean And 
&= 
Bitwise Xor 
^= 
Boolean Xor 
^= 
Bitwise Or 
= 
Boolean Or 
= 
Examples:
int i = 10; // declares the variable i and sets it to constant int 10 i *= 2; // multiplies i by 2  i = (int)(i * 2) i /= 5; // divides i by 5  i = (int)(i / 5) i %= 3; // gives the remainder for i/3  i = (int)(i % 3) i += 5; // adds 5 to i  i = (int)(i + 5) i = 5; // subtracts 5 from i  i = (int)(i  5) i <<= 2; // left shifts i by 2  i = (int)(i << 2) i >>= 1; // right shifts i by 1  i = (int)(i >> 1) i >>>= 1; // unsigned right shifts i by 1  i = (int)(i >>> 1) i &= 15; // ands i with 15  i = (int)(i & 15) i ^= 12; // xors i with 12  i = (int)(i ^ 2) i = 4; // ors i with 4  i = (int)(i  4) boolean b = true; // declares the boolean variable b and sets it to the constant boolean true b &= false; // ands b with false  b = (boolean)(b & false) b ^= false; // xors b with false  b = (boolean)(b & false) b = true; // ors be with true  b = (boolean)(b & false) def x = 'compound'; // declares the def variable x and sets it to the constant String 'compound' x += ' assignment'; // string concatenates ' assignment' to x  x = (String)(x + ' assignment')