1421 lines
45 KiB
Plaintext
1421 lines
45 KiB
Plaintext
|
[[painless-operators-boolean]]
|
||
|
=== Operators: Boolean
|
||
|
|
||
|
[[boolean-not-operator]]
|
||
|
==== Boolean Not
|
||
|
|
||
|
Use the `boolean not operator '!'` to NOT a `boolean` type value where `true` is
|
||
|
flipped to `false` and `false` is flipped to `true`.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If a value other than a `boolean` type value or a value that is castable to a
|
||
|
`boolean` type value is given.
|
||
|
|
||
|
*Truth*
|
||
|
|
||
|
[options="header",cols="<1,<1"]
|
||
|
|====
|
||
|
| original | result
|
||
|
| true | false
|
||
|
| false | true
|
||
|
|====
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
boolean_not: '!' expression;
|
||
|
----
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Boolean not with the `boolean` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = !false;
|
||
|
<2> boolean y = !x;
|
||
|
----
|
||
|
<1> declare `boolean x`;
|
||
|
boolean not `boolean false` -> `boolean true`;
|
||
|
store `boolean true` to `x`
|
||
|
<2> declare `boolean y`;
|
||
|
load from `x` -> `boolean true`;
|
||
|
boolean not `boolean true` -> `boolean false`;
|
||
|
store `boolean false` to `y`
|
||
|
+
|
||
|
* Boolean not with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> def y = true;
|
||
|
<2> def z = !y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def y`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `true` to `y`
|
||
|
<2> declare `def z`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `boolean true` -> boolean `true`;
|
||
|
boolean not `boolean true` -> `boolean false`;
|
||
|
implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
|
||
|
[[greater-than-operator]]
|
||
|
==== Greater Than
|
||
|
|
||
|
Use the `greater than operator '>'` to COMPARE two numeric type values where a
|
||
|
resultant `boolean` type value is `true` if the left-hand side value is greater
|
||
|
than to the right-hand side value and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either the evaluated left-hand side or the evaluated right-hand side is a
|
||
|
non-numeric value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
greater_than: expression '>' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | 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*
|
||
|
|
||
|
* Greater than with different numeric types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = 5 > 4;
|
||
|
<2> double y = 6.0;
|
||
|
<3> x = 6 > y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
greater than `int 5` and `int 4` -> `boolean true`;
|
||
|
store `boolean true` to `x`;
|
||
|
<2> declare `double y`;
|
||
|
store `double 6.0` to `y`;
|
||
|
<3> load from `y` -> `double 6.0 @0`;
|
||
|
promote `int 6` and `double 6.0`: result `double`;
|
||
|
implicit cast `int 6` to `double 6.0 @1` -> `double 6.0 @1`;
|
||
|
greater than `double 6.0 @1` and `double 6.0 @0` -> `boolean false`;
|
||
|
store `boolean false` to `x`
|
||
|
+
|
||
|
* Greater than with `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> int x = 5;
|
||
|
<2> def y = 7.0;
|
||
|
<3> def z = y > 6.5;
|
||
|
<4> def a = x > y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `int x`;
|
||
|
store `int 5` to `x`
|
||
|
<2> declare `def y`;
|
||
|
implicit cast `double 7.0` to `def` -> `def`;
|
||
|
store `def` to `y`
|
||
|
<3> declare `def z`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0` -> `double 7.0`;
|
||
|
greater than `double 7.0` and `double 6.5` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
<4> declare `def a`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0` -> `double 7.0`;
|
||
|
load from `x` -> `int 5`;
|
||
|
promote `int 5` and `double 7.0`: result `double`;
|
||
|
implicit cast `int 5` to `double 5.0` -> `double 5.0`;
|
||
|
greater than `double 5.0` and `double 7.0` -> `boolean false`;
|
||
|
implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
|
||
|
[[greater-than-or-equal-operator]]
|
||
|
==== Greater Than Or Equal
|
||
|
|
||
|
Use the `greater than or equal operator '>='` to COMPARE two numeric type values
|
||
|
where a resultant `boolean` type value is `true` if the left-hand side value is
|
||
|
greater than or equal to the right-hand side value and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either the evaluated left-hand side or the evaluated right-hand side is a
|
||
|
non-numeric value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
greater_than_or_equal: expression '>=' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | 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*
|
||
|
|
||
|
* Greater than or equal with different numeric types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = 5 >= 4;
|
||
|
<2> double y = 6.0;
|
||
|
<3> x = 6 >= y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
greater than or equal `int 5` and `int 4` -> `boolean true`;
|
||
|
store `boolean true` to `x`
|
||
|
<2> declare `double y`;
|
||
|
store `double 6.0` to `y`
|
||
|
<3> load from `y` -> `double 6.0 @0`;
|
||
|
promote `int 6` and `double 6.0`: result `double`;
|
||
|
implicit cast `int 6` to `double 6.0 @1` -> `double 6.0 @1`;
|
||
|
greater than or equal `double 6.0 @1` and `double 6.0 @0` -> `boolean true`;
|
||
|
store `boolean true` to `x`
|
||
|
+
|
||
|
* Greater than or equal with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> int x = 5;
|
||
|
<2> def y = 7.0;
|
||
|
<3> def z = y >= 7.0;
|
||
|
<4> def a = x >= y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `int x`;
|
||
|
store `int 5` to `x`;
|
||
|
<2> declare `def y`
|
||
|
implicit cast `double 7.0` to `def` -> `def`;
|
||
|
store `def` to `y`
|
||
|
<3> declare `def z`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0 @0` -> `double 7.0 @0`;
|
||
|
greater than or equal `double 7.0 @0` and `double 7.0 @1` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
<4> declare `def a`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0` -> `double 7.0`;
|
||
|
load from `x` -> `int 5`;
|
||
|
promote `int 5` and `double 7.0`: result `double`;
|
||
|
implicit cast `int 5` to `double 5.0` -> `double 5.0`;
|
||
|
greater than or equal `double 5.0` and `double 7.0` -> `boolean false`;
|
||
|
implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
|
||
|
[[less-than-operator]]
|
||
|
==== Less Than
|
||
|
|
||
|
Use the `less than operator '<'` to COMPARE two numeric type values where a
|
||
|
resultant `boolean` type value is `true` if the left-hand side value is less
|
||
|
than to the right-hand side value and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either the evaluated left-hand side or the evaluated right-hand side is a
|
||
|
non-numeric value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
less_than: expression '<' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | 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*
|
||
|
|
||
|
* Less than with different numeric types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = 5 < 4;
|
||
|
<2> double y = 6.0;
|
||
|
<3> x = 6 < y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
less than `int 5` and `int 4` -> `boolean false`;
|
||
|
store `boolean false` to `x`
|
||
|
<2> declare `double y`;
|
||
|
store `double 6.0` to `y`
|
||
|
<3> load from `y` -> `double 6.0 @0`;
|
||
|
promote `int 6` and `double 6.0`: result `double`;
|
||
|
implicit cast `int 6` to `double 6.0 @1` -> `double 6.0 @1`;
|
||
|
less than `double 6.0 @1` and `double 6.0 @0` -> `boolean false`;
|
||
|
store `boolean false` to `x`
|
||
|
+
|
||
|
* Less than with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> int x = 5;
|
||
|
<2> def y = 7.0;
|
||
|
<3> def z = y < 6.5;
|
||
|
<4> def a = x < y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `int x`;
|
||
|
store `int 5` to `x`
|
||
|
<2> declare `def y`;
|
||
|
implicit cast `double 7.0` to `def` -> `def`;
|
||
|
store `def` to `y`
|
||
|
<3> declare `def z`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0` -> `double 7.0`;
|
||
|
less than `double 7.0` and `double 6.5` -> `boolean false`;
|
||
|
implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
<4> declare `def a`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0` -> `double 7.0`;
|
||
|
load from `x` -> `int 5`;
|
||
|
promote `int 5` and `double 7.0`: result `double`;
|
||
|
implicit cast `int 5` to `double 5.0` -> `double 5.0`;
|
||
|
less than `double 5.0` and `double 7.0` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
|
||
|
[[less-than-or-equal-operator]]
|
||
|
==== Less Than Or Equal
|
||
|
|
||
|
Use the `less than or equal operator '<='` to COMPARE two numeric type values
|
||
|
where a resultant `boolean` type value is `true` if the left-hand side value is
|
||
|
less than or equal to the right-hand side value and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either the evaluated left-hand side or the evaluated right-hand side is a
|
||
|
non-numeric value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
greater_than_or_equal: expression '<=' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | 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*
|
||
|
|
||
|
* Less than or equal with different numeric types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = 5 <= 4;
|
||
|
<2> double y = 6.0;
|
||
|
<3> x = 6 <= y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
less than or equal `int 5` and `int 4` -> `boolean false`;
|
||
|
store `boolean true` to `x`
|
||
|
<2> declare `double y`;
|
||
|
store `double 6.0` to `y`
|
||
|
<3> load from `y` -> `double 6.0 @0`;
|
||
|
promote `int 6` and `double 6.0`: result `double`;
|
||
|
implicit cast `int 6` to `double 6.0 @1` -> `double 6.0 @1`;
|
||
|
less than or equal `double 6.0 @1` and `double 6.0 @0` -> `boolean true`;
|
||
|
store `boolean true` to `x`
|
||
|
+
|
||
|
* Less than or equal with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> int x = 5;
|
||
|
<2> def y = 7.0;
|
||
|
<3> def z = y <= 7.0;
|
||
|
<4> def a = x <= y;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `int x`;
|
||
|
store `int 5` to `x`;
|
||
|
<2> declare `def y`;
|
||
|
implicit cast `double 7.0` to `def` -> `def`;
|
||
|
store `def` to `y`;
|
||
|
<3> declare `def z`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0 @0` -> `double 7.0 @0`;
|
||
|
less than or equal `double 7.0 @0` and `double 7.0 @1` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
<4> declare `def a`;
|
||
|
load from `y` -> `def`;
|
||
|
implicit cast `def` to `double 7.0` -> `double 7.0`;
|
||
|
load from `x` -> `int 5`;
|
||
|
promote `int 5` and `double 7.0`: result `double`;
|
||
|
implicit cast `int 5` to `double 5.0` -> `double 5.0`;
|
||
|
less than or equal `double 5.0` and `double 7.0` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `z`
|
||
|
|
||
|
[[instanceof-operator]]
|
||
|
==== Instanceof
|
||
|
|
||
|
Use the `instanceof operator` to COMPARE the variable/field type to a
|
||
|
specified reference type using the reference type name where a resultant
|
||
|
`boolean` type value is `true` if the variable/field type is the same as or a
|
||
|
descendant of the specified reference type and false otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If the reference type name doesn't exist as specified by the right-hand side.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
instance_of: ID 'instanceof' TYPE;
|
||
|
----
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Instance of with different reference types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> Map m = new HashMap();
|
||
|
<2> boolean a = m instanceof HashMap;
|
||
|
<3> boolean b = m instanceof Map;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `Map m`;
|
||
|
allocate `HashMap` instance -> `HashMap reference`;
|
||
|
implicit cast `HashMap reference` to `Map reference`;
|
||
|
store `Map reference` to `m`
|
||
|
<2> declare `boolean a`;
|
||
|
load from `m` -> `Map reference`;
|
||
|
implicit cast `Map reference` to `HashMap reference` -> `HashMap reference`;
|
||
|
instanceof `HashMap reference` and `HashMap` -> `boolean true`;
|
||
|
store `boolean true` to `a`
|
||
|
<3> declare `boolean b`;
|
||
|
load from `m` -> `Map reference`;
|
||
|
implicit cast `Map reference` to `HashMap reference` -> `HashMap reference`;
|
||
|
instanceof `HashMap reference` and `Map` -> `boolean true`;
|
||
|
store `true` to `b`;
|
||
|
(note `HashMap` is a descendant of `Map`)
|
||
|
+
|
||
|
* Instance of with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> def d = new ArrayList();
|
||
|
<2> boolean a = d instanceof List;
|
||
|
<3> boolean b = d instanceof Map;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def d`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `def` -> `def`;
|
||
|
store `def` to `d`
|
||
|
<2> declare `boolean a`;
|
||
|
load from `d` -> `def`;
|
||
|
implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
|
||
|
instanceof `ArrayList reference` and `List` -> `boolean true`;
|
||
|
store `boolean true` to `a`;
|
||
|
(note `ArrayList` is a descendant of `List`)
|
||
|
<3> declare `boolean b`;
|
||
|
load from `d` -> `def`;
|
||
|
implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
|
||
|
instanceof `ArrayList reference` and `Map` -> `boolean false`;
|
||
|
store `boolean false` to `a`;
|
||
|
(note `ArrayList` is not a descendant of `Map`)
|
||
|
|
||
|
[[equality-equals-operator]]
|
||
|
==== Equality Equals
|
||
|
|
||
|
Use the `equality equals operator '=='` to COMPARE two values where a resultant
|
||
|
`boolean` type value is `true` if the two values are equal and `false`
|
||
|
otherwise. The member method, `equals`, is implicitly called when the values are
|
||
|
reference type values where the first value is the target of the call and the
|
||
|
second value is the argument. This operation is null-safe where if both values
|
||
|
are `null` the resultant `boolean` type value is `true`, and if only one value
|
||
|
is `null` the resultant `boolean` type value is `false`. A valid comparison is
|
||
|
between `boolean` type values, numeric type values, or reference type values.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If a comparison is made between a `boolean` type value and numeric type value.
|
||
|
* If a comparison is made between a primitive type value and a reference type
|
||
|
value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
equality_equals: expression '==' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | boolean | byte | short | char | int | long | float | double | Reference | def
|
||
|
| boolean | boolean | - | - | - | - | - | - | - | - | 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
|
||
|
| Reference | - | - | - | - | - | - | - | - | Object | def
|
||
|
| def | def | def | def | def | def | def | def | def | def | def
|
||
|
|====
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Equality equals with the `boolean` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean a = true;
|
||
|
<2> boolean b = false;
|
||
|
<3> a = a == false;
|
||
|
<4> b = a == b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean a`;
|
||
|
store `boolean true` to `a`
|
||
|
<2> declare `boolean b`;
|
||
|
store `boolean false` to `b`
|
||
|
<3> load from `a` -> `boolean true`;
|
||
|
equality equals `boolean true` and `boolean false` -> `boolean false`;
|
||
|
store `boolean false` to `a`
|
||
|
<4> load from `a` -> `boolean false @0`;
|
||
|
load from `b` -> `boolean false @1`;
|
||
|
equality equals `boolean false @0` and `boolean false @1`
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `b`
|
||
|
+
|
||
|
* Equality equals with primitive types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> int a = 1;
|
||
|
<2> double b = 2.0;
|
||
|
<3> boolean c = a == b;
|
||
|
<4> c = 1 == a;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `int a`;
|
||
|
store `int 1` to `a`
|
||
|
<2> declare `double b`;
|
||
|
store `double 1.0` to `b`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `int 1`;
|
||
|
load from `b` -> `double 2.0`;
|
||
|
promote `int 1` and `double 2.0`: result `double`;
|
||
|
implicit cast `int 1` to `double 1.0` -> `double `1.0`;
|
||
|
equality equals `double 1.0` and `double 2.0` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<4> load from `a` -> `int 1 @1`;
|
||
|
equality equals `int 1 @0` and `int 1 @1` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
+
|
||
|
* Equal equals with reference types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> List a = new ArrayList();
|
||
|
<2> List b = new ArrayList();
|
||
|
<3> a.add(1);
|
||
|
<4> boolean c = a == b;
|
||
|
<5> b.add(1);
|
||
|
<6> c = a == b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `List a`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `a`
|
||
|
<2> declare `List b`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `b`
|
||
|
<3> load from `a` -> `List reference`;
|
||
|
call `add` on `List reference` with arguments (`int 1)`
|
||
|
<4> declare `boolean c`;
|
||
|
load from `a` -> `List reference @0`;
|
||
|
load from `b` -> `List reference @1`;
|
||
|
call `equals` on `List reference @0` with arguments (`List reference @1`)
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<5> load from `b` -> `List reference`;
|
||
|
call `add` on `List reference` with arguments (`int 1`)
|
||
|
<6> load from `a` -> `List reference @0`;
|
||
|
load from `b` -> `List reference @1`;
|
||
|
call `equals` on `List reference @0` with arguments (`List reference @1`)
|
||
|
-> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
+
|
||
|
* Equality equals with `null`.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> Object a = null;
|
||
|
<2> Object b = null;
|
||
|
<3> boolean c = a == null;
|
||
|
<4> c = a == b;
|
||
|
<5> b = new Object();
|
||
|
<6> c = a == b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `Object a`;
|
||
|
store `null` to `a`
|
||
|
<2> declare `Object b`;
|
||
|
store `null` to `b`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `null @0`;
|
||
|
equality equals `null @0` and `null @1` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
<4> load from `a` -> `null @0`;
|
||
|
load from `b` -> `null @1`;
|
||
|
equality equals `null @0` and `null @1` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
<5> allocate `Object` instance -> `Object reference`;
|
||
|
store `Object reference` to `b`
|
||
|
<6> load from `a` -> `Object reference`;
|
||
|
load from `b` -> `null`;
|
||
|
call `equals` on `Object reference` with arguments (`null`)
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
+
|
||
|
* Equality equals with the `def` type.
|
||
|
+
|
||
|
[source, Painless]
|
||
|
----
|
||
|
<1> def a = 0;
|
||
|
<2> def b = 1;
|
||
|
<3> boolean c = a == b;
|
||
|
<4> def d = new HashMap();
|
||
|
<5> def e = new ArrayList();
|
||
|
<6> c = d == e;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def a`;
|
||
|
implicit cast `int 0` to `def` -> `def`;
|
||
|
store `def` to `a`;
|
||
|
<2> declare `def b`;
|
||
|
implicit cast `int 1` to `def` -> `def`;
|
||
|
store `def` to `b`;
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `def`;
|
||
|
implicit cast `a` to `int 0` -> `int 0`;
|
||
|
load from `b` -> `def`;
|
||
|
implicit cast `b` to `int 1` -> `int 1`;
|
||
|
equality equals `int 0` and `int 1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<4> declare `def d`;
|
||
|
allocate `HashMap` instance -> `HashMap reference`;
|
||
|
implicit cast `HashMap reference` to `def` -> `def`
|
||
|
store `def` to `d`;
|
||
|
<5> declare `def e`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `def` -> `def`
|
||
|
store `def` to `d`;
|
||
|
<6> load from `d` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference` -> `HashMap reference`;
|
||
|
load from `e` -> `def`;
|
||
|
implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
|
||
|
call `equals` on `HashMap reference` with arguments (`ArrayList reference`)
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
|
||
|
[[equality-not-equals-operator]]
|
||
|
==== Equality Not Equals
|
||
|
|
||
|
Use the `equality not equals operator '!='` to COMPARE two values where a
|
||
|
resultant `boolean` type value is `true` if the two values are NOT equal and
|
||
|
`false` otherwise. The member method, `equals`, is implicitly called when the
|
||
|
values are reference type values where the first value is the target of the call
|
||
|
and the second value is the argument with the resultant `boolean` type value
|
||
|
flipped. This operation is `null-safe` where if both values are `null` the
|
||
|
resultant `boolean` type value is `false`, and if only one value is `null` the
|
||
|
resultant `boolean` type value is `true`. A valid comparison is between boolean
|
||
|
type values, numeric type values, or reference type values.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If a comparison is made between a `boolean` type value and numeric type value.
|
||
|
* If a comparison is made between a primitive type value and a reference type
|
||
|
value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
equality_not_equals: expression '!=' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | boolean | byte | short | char | int | long | float | double | Reference | def
|
||
|
| boolean | boolean | - | - | - | - | - | - | - | - | 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
|
||
|
| Reference | - | - | - | - | - | - | - | - | Object | def
|
||
|
| def | def | def | def | def | def | def | def | def | def | def
|
||
|
|====
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Equality not equals with the `boolean` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean a = true;
|
||
|
<2> boolean b = false;
|
||
|
<3> a = a != false;
|
||
|
<4> b = a != b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean a`;
|
||
|
store `boolean true` to `a`
|
||
|
<2> declare `boolean b`;
|
||
|
store `boolean false` to `b`
|
||
|
<3> load from `a` -> `boolean true`;
|
||
|
equality not equals `boolean true` and `boolean false` -> `boolean true`;
|
||
|
store `boolean true` to `a`
|
||
|
<4> load from `a` -> `boolean true`;
|
||
|
load from `b` -> `boolean false`;
|
||
|
equality not equals `boolean true` and `boolean false` -> `boolean true`;
|
||
|
store `boolean true` to `b`
|
||
|
+
|
||
|
* Equality not equals with primitive types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> int a = 1;
|
||
|
<2> double b = 2.0;
|
||
|
<3> boolean c = a != b;
|
||
|
<4> c = 1 != a;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `int a`;
|
||
|
store `int 1` to `a`
|
||
|
<2> declare `double b`;
|
||
|
store `double 1.0` to `b`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `int 1`;
|
||
|
load from `b` -> `double 2.0`;
|
||
|
promote `int 1` and `double 2.0`: result `double`;
|
||
|
implicit cast `int 1` to `double 1.0` -> `double `1.0`;
|
||
|
equality not equals `double 1.0` and `double 2.0` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
<4> load from `a` -> `int 1 @1`;
|
||
|
equality not equals `int 1 @0` and `int 1 @1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
+
|
||
|
* Equality not equals with reference types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> List a = new ArrayList();
|
||
|
<2> List b = new ArrayList();
|
||
|
<3> a.add(1);
|
||
|
<4> boolean c = a == b;
|
||
|
<5> b.add(1);
|
||
|
<6> c = a == b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `List a`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `a`
|
||
|
<2> declare `List b`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `b`
|
||
|
<3> load from `a` -> `List reference`;
|
||
|
call `add` on `List reference` with arguments (`int 1)`
|
||
|
<4> declare `boolean c`;
|
||
|
load from `a` -> `List reference @0`;
|
||
|
load from `b` -> `List reference @1`;
|
||
|
call `equals` on `List reference @0` with arguments (`List reference @1`)
|
||
|
-> `boolean false`;
|
||
|
boolean not `boolean false` -> `boolean true`
|
||
|
store `boolean true` to `c`
|
||
|
<5> load from `b` -> `List reference`;
|
||
|
call `add` on `List reference` with arguments (`int 1`)
|
||
|
<6> load from `a` -> `List reference @0`;
|
||
|
load from `b` -> `List reference @1`;
|
||
|
call `equals` on `List reference @0` with arguments (`List reference @1`)
|
||
|
-> `boolean true`;
|
||
|
boolean not `boolean true` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
+
|
||
|
* Equality not equals with `null`.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> Object a = null;
|
||
|
<2> Object b = null;
|
||
|
<3> boolean c = a == null;
|
||
|
<4> c = a == b;
|
||
|
<5> b = new Object();
|
||
|
<6> c = a == b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `Object a`;
|
||
|
store `null` to `a`
|
||
|
<2> declare `Object b`;
|
||
|
store `null` to `b`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `null @0`;
|
||
|
equality not equals `null @0` and `null @1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<4> load from `a` -> `null @0`;
|
||
|
load from `b` -> `null @1`;
|
||
|
equality not equals `null @0` and `null @1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<5> allocate `Object` instance -> `Object reference`;
|
||
|
store `Object reference` to `b`
|
||
|
<6> load from `a` -> `Object reference`;
|
||
|
load from `b` -> `null`;
|
||
|
call `equals` on `Object reference` with arguments (`null`)
|
||
|
-> `boolean false`;
|
||
|
boolean not `boolean false` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
+
|
||
|
* Equality not equals with the `def` type.
|
||
|
+
|
||
|
[source, Painless]
|
||
|
----
|
||
|
<1> def a = 0;
|
||
|
<2> def b = 1;
|
||
|
<3> boolean c = a == b;
|
||
|
<4> def d = new HashMap();
|
||
|
<5> def e = new ArrayList();
|
||
|
<6> c = d == e;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def a`;
|
||
|
implicit cast `int 0` to `def` -> `def`;
|
||
|
store `def` to `a`;
|
||
|
<2> declare `def b`;
|
||
|
implicit cast `int 1` to `def` -> `def`;
|
||
|
store `def` to `b`;
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `def`;
|
||
|
implicit cast `a` to `int 0` -> `int 0`;
|
||
|
load from `b` -> `def`;
|
||
|
implicit cast `b` to `int 1` -> `int 1`;
|
||
|
equality equals `int 0` and `int 1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<4> declare `def d`;
|
||
|
allocate `HashMap` instance -> `HashMap reference`;
|
||
|
implicit cast `HashMap reference` to `def` -> `def`
|
||
|
store `def` to `d`;
|
||
|
<5> declare `def e`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `def` -> `def`
|
||
|
store `def` to `d`;
|
||
|
<6> load from `d` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference` -> `HashMap reference`;
|
||
|
load from `e` -> `def`;
|
||
|
implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
|
||
|
call `equals` on `HashMap reference` with arguments (`ArrayList reference`)
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
|
||
|
[[identity-equals-operator]]
|
||
|
==== Identity Equals
|
||
|
|
||
|
Use the `identity equals operator '==='` to COMPARE two values where a resultant
|
||
|
`boolean` type value is `true` if the two values are equal and `false`
|
||
|
otherwise. A reference type value is equal to another reference type value if
|
||
|
both values refer to same instance on the heap or if both values are `null`. A
|
||
|
valid comparison is between `boolean` type values, numeric type values, or
|
||
|
reference type values.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If a comparison is made between a `boolean` type value and numeric type value.
|
||
|
* If a comparison is made between a primitive type value and a reference type
|
||
|
value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
identity_equals: expression '===' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | boolean | byte | short | char | int | long | float | double | Reference | def
|
||
|
| boolean | boolean | - | - | - | - | - | - | - | - | 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
|
||
|
| Reference | - | - | - | - | - | - | - | - | Object | def
|
||
|
| def | def | def | def | def | def | def | def | def | def | def
|
||
|
|====
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Identity equals with reference types.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> List a = new ArrayList();
|
||
|
<2> List b = new ArrayList();
|
||
|
<3> List c = a;
|
||
|
<4> boolean c = a === b;
|
||
|
<5> c = a === c;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `List a`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `a`
|
||
|
<2> declare `List b`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `b`
|
||
|
<3> load from `a` -> `List reference`;
|
||
|
store `List reference` to `c`
|
||
|
<4> declare `boolean c`;
|
||
|
load from `a` -> `List reference @0`;
|
||
|
load from `b` -> `List reference @1`;
|
||
|
identity equals `List reference @0` and `List reference @1`
|
||
|
-> `boolean false`
|
||
|
store `boolean false` to `c`
|
||
|
<5> load from `a` -> `List reference @0`;
|
||
|
load from `c` -> `List reference @1`;
|
||
|
identity equals `List reference @0` and `List reference @1`
|
||
|
-> `boolean true`
|
||
|
store `boolean true` to `c`
|
||
|
(note `List reference @0` and `List reference @1` refer to the same
|
||
|
instance)
|
||
|
+
|
||
|
* Identity equals with `null`.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> Object a = null;
|
||
|
<2> Object b = null;
|
||
|
<3> boolean c = a === null;
|
||
|
<4> c = a === b;
|
||
|
<5> b = new Object();
|
||
|
<6> c = a === b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `Object a`;
|
||
|
store `null` to `a`
|
||
|
<2> declare `Object b`;
|
||
|
store `null` to `b`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `null @0`;
|
||
|
identity equals `null @0` and `null @1` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
<4> load from `a` -> `null @0`;
|
||
|
load from `b` -> `null @1`;
|
||
|
identity equals `null @0` and `null @1` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
<5> allocate `Object` instance -> `Object reference`;
|
||
|
store `Object reference` to `b`
|
||
|
<6> load from `a` -> `Object reference`;
|
||
|
load from `b` -> `null`;
|
||
|
identity equals `Object reference` and `null` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
+
|
||
|
* Identity equals with the `def` type.
|
||
|
+
|
||
|
[source, Painless]
|
||
|
----
|
||
|
<1> def a = new HashMap();
|
||
|
<2> def b = new ArrayList();
|
||
|
<3> boolean c = a === b;
|
||
|
<4> b = a;
|
||
|
<5> c = a === b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def d`;
|
||
|
allocate `HashMap` instance -> `HashMap reference`;
|
||
|
implicit cast `HashMap reference` to `def` -> `def`
|
||
|
store `def` to `d`
|
||
|
<2> declare `def e`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `def` -> `def`
|
||
|
store `def` to `d`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference` -> `HashMap reference`;
|
||
|
load from `b` -> `def`;
|
||
|
implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
|
||
|
identity equals `HashMap reference` and `ArrayList reference`
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<4> load from `a` -> `def`;
|
||
|
store `def` to `b`
|
||
|
<5> load from `a` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference @0` -> `HashMap reference @0`;
|
||
|
load from `b` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference @1` -> `HashMap reference @1`;
|
||
|
identity equals `HashMap reference @0` and `HashMap reference @1`
|
||
|
-> `boolean true`;
|
||
|
store `boolean true` to `b`;
|
||
|
(note `HashMap reference @0` and `HashMap reference @1` refer to the same
|
||
|
instance)
|
||
|
|
||
|
[[identity-not-equals-operator]]
|
||
|
==== Identity Not Equals
|
||
|
|
||
|
Use the `identity not equals operator '!=='` to COMPARE two values where a
|
||
|
resultant `boolean` type value is `true` if the two values are NOT equal and
|
||
|
`false` otherwise. A reference type value is not equal to another reference type
|
||
|
value if both values refer to different instances on the heap or if one value is
|
||
|
`null` and the other is not. A valid comparison is between `boolean` type
|
||
|
values, numeric type values, or reference type values.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If a comparison is made between a `boolean` type value and numeric type value.
|
||
|
* If a comparison is made between a primitive type value and a reference type
|
||
|
value.
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
identity_not_equals: expression '!==' expression;
|
||
|
----
|
||
|
|
||
|
*Promotion*
|
||
|
|
||
|
[cols="<1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1"]
|
||
|
|====
|
||
|
| | boolean | byte | short | char | int | long | float | double | Reference | def
|
||
|
| boolean | boolean | - | - | - | - | - | - | - | - | 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
|
||
|
| Reference | - | - | - | - | - | - | - | - | Object | def
|
||
|
| def | def | def | def | def | def | def | def | def | def | def
|
||
|
|====
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Identity not equals with reference type values.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> List a = new ArrayList();
|
||
|
<2> List b = new ArrayList();
|
||
|
<3> List c = a;
|
||
|
<4> boolean c = a !== b;
|
||
|
<5> c = a !== c;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `List a`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `a`
|
||
|
<2> declare `List b`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `List reference` -> `List reference`;
|
||
|
store `List reference` to `b`
|
||
|
<3> load from `a` -> `List reference`;
|
||
|
store `List reference` to `c`
|
||
|
<4> declare `boolean c`;
|
||
|
load from `a` -> `List reference @0`;
|
||
|
load from `b` -> `List reference @1`;
|
||
|
identity not equals `List reference @0` and `List reference @1`
|
||
|
-> `boolean true`
|
||
|
store `boolean true` to `c`
|
||
|
<5> load from `a` -> `List reference @0`;
|
||
|
load from `c` -> `List reference @1`;
|
||
|
identity not equals `List reference @0` and `List reference @1`
|
||
|
-> `boolean false`
|
||
|
store `boolean false` to `c`
|
||
|
(note `List reference @0` and `List reference @1` refer to the same
|
||
|
instance)
|
||
|
+
|
||
|
* Identity not equals with `null`.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> Object a = null;
|
||
|
<2> Object b = null;
|
||
|
<3> boolean c = a !== null;
|
||
|
<4> c = a !== b;
|
||
|
<5> b = new Object();
|
||
|
<6> c = a !== b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `Object a`;
|
||
|
store `null` to `a`
|
||
|
<2> declare `Object b`;
|
||
|
store `null` to `b`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `null @0`;
|
||
|
identity not equals `null @0` and `null @1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<4> load from `a` -> `null @0`;
|
||
|
load from `b` -> `null @1`;
|
||
|
identity not equals `null @0` and `null @1` -> `boolean false`;
|
||
|
store `boolean false` to `c`
|
||
|
<5> allocate `Object` instance -> `Object reference`;
|
||
|
store `Object reference` to `b`
|
||
|
<6> load from `a` -> `Object reference`;
|
||
|
load from `b` -> `null`;
|
||
|
identity not equals `Object reference` and `null` -> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
+
|
||
|
* Identity not equals with the `def` type.
|
||
|
+
|
||
|
[source, Painless]
|
||
|
----
|
||
|
<1> def a = new HashMap();
|
||
|
<2> def b = new ArrayList();
|
||
|
<3> boolean c = a !== b;
|
||
|
<4> b = a;
|
||
|
<5> c = a !== b;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def d`;
|
||
|
allocate `HashMap` instance -> `HashMap reference`;
|
||
|
implicit cast `HashMap reference` to `def` -> `def`
|
||
|
store `def` to `d`
|
||
|
<2> declare `def e`;
|
||
|
allocate `ArrayList` instance -> `ArrayList reference`;
|
||
|
implicit cast `ArrayList reference` to `def` -> `def`
|
||
|
store `def` to `d`
|
||
|
<3> declare `boolean c`;
|
||
|
load from `a` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference` -> `HashMap reference`;
|
||
|
load from `b` -> `def`;
|
||
|
implicit cast `def` to `ArrayList reference` -> `ArrayList reference`;
|
||
|
identity not equals `HashMap reference` and `ArrayList reference`
|
||
|
-> `boolean true`;
|
||
|
store `boolean true` to `c`
|
||
|
<4> load from `a` -> `def`;
|
||
|
store `def` to `b`
|
||
|
<5> load from `a` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference @0` -> `HashMap reference @0`;
|
||
|
load from `b` -> `def`;
|
||
|
implicit cast `def` to `HashMap reference @1` -> `HashMap reference @1`;
|
||
|
identity not equals `HashMap reference @0` and `HashMap reference @1`
|
||
|
-> `boolean false`;
|
||
|
store `boolean false` to `b`;
|
||
|
(note `HashMap reference @0` and `HashMap reference @1` refer to the same
|
||
|
instance)
|
||
|
|
||
|
[[boolean-xor-operator]]
|
||
|
==== Boolean Xor
|
||
|
|
||
|
Use the `boolean xor operator '^'` to XOR together two `boolean` type values
|
||
|
where if one `boolean` type value is `true` and the other is `false` the
|
||
|
resultant `boolean` type value is `true` and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either evaluated value is a value other than a `boolean` type value or
|
||
|
a value that is castable to a `boolean` type value.
|
||
|
|
||
|
*Truth*
|
||
|
|
||
|
[cols="^1,^1,^1"]
|
||
|
|====
|
||
|
| | true | false
|
||
|
| true | false | true
|
||
|
| false | true | false
|
||
|
|====
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
boolean_xor: expression '^' expression;
|
||
|
----
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Boolean xor with the `boolean` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = false;
|
||
|
<2> boolean y = x ^ true;
|
||
|
<3> y = y ^ x;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
store `boolean false` to `x`
|
||
|
<2> declare `boolean y`;
|
||
|
load from `x` -> `boolean false`
|
||
|
boolean xor `boolean false` and `boolean true` -> `boolean true`;
|
||
|
store `boolean true` to `y`
|
||
|
<3> load from `y` -> `boolean true @0`;
|
||
|
load from `x` -> `boolean true @1`;
|
||
|
boolean xor `boolean true @0` and `boolean true @1` -> `boolean false`;
|
||
|
store `boolean false` to `y`
|
||
|
+
|
||
|
* Boolean xor with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> def x = false;
|
||
|
<2> def y = x ^ true;
|
||
|
<3> y = y ^ x;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def x`;
|
||
|
implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `x`
|
||
|
<2> declare `def y`;
|
||
|
load from `x` -> `def`;
|
||
|
implicit cast `def` to `boolean false` -> `boolean false`;
|
||
|
boolean xor `boolean false` and `boolean true` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `y`
|
||
|
<3> load from `y` -> `def`;
|
||
|
implicit cast `def` to `boolean true @0` -> `boolean true @0`;
|
||
|
load from `x` -> `def`;
|
||
|
implicit cast `def` to `boolean true @1` -> `boolean true @1`;
|
||
|
boolean xor `boolean true @0` and `boolean true @1` -> `boolean false`;
|
||
|
implicit cast `boolean false` -> `def`;
|
||
|
store `def` to `y`
|
||
|
|
||
|
[[boolean-and-operator]]
|
||
|
==== Boolean And
|
||
|
|
||
|
Use the `boolean and operator '&&'` to AND together two `boolean` type values
|
||
|
where if both `boolean` type values are `true` the resultant `boolean` type
|
||
|
value is `true` and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either evaluated value is a value other than a `boolean` type value or
|
||
|
a value that is castable to a `boolean` type value.
|
||
|
|
||
|
*Truth*
|
||
|
|
||
|
[cols="^1,^1,^1"]
|
||
|
|====
|
||
|
| | true | false
|
||
|
| true | true | false
|
||
|
| false | false | false
|
||
|
|====
|
||
|
|
||
|
*Grammar*
|
||
|
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
boolean_and: expression '&&' expression;
|
||
|
----
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Boolean and with the `boolean` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = true;
|
||
|
<2> boolean y = x && true;
|
||
|
<3> x = false;
|
||
|
<4> y = y && x;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
store `boolean true` to `x`
|
||
|
<2> declare `boolean y`;
|
||
|
load from `x` -> `boolean true @0`;
|
||
|
boolean and `boolean true @0` and `boolean true @1` -> `boolean true`;
|
||
|
store `boolean true` to `y`
|
||
|
<3> store `boolean false` to `x`
|
||
|
<4> load from `y` -> `boolean true`;
|
||
|
load from `x` -> `boolean false`;
|
||
|
boolean and `boolean true` and `boolean false` -> `boolean false`;
|
||
|
store `boolean false` to `y`
|
||
|
+
|
||
|
* Boolean and with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> def x = true;
|
||
|
<2> def y = x && true;
|
||
|
<3> x = false;
|
||
|
<4> y = y && x;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def x`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `x`
|
||
|
<2> declare `def y`;
|
||
|
load from `x` -> `def`;
|
||
|
implicit cast `def` to `boolean true @0` -> `boolean true @0`;
|
||
|
boolean and `boolean true @0` and `boolean true @1` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `y`
|
||
|
<3> implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `x`;
|
||
|
<4> load from `y` -> `def`;
|
||
|
implicit cast `def` to `boolean true` -> `boolean true`;
|
||
|
load from `x` -> `def`;
|
||
|
implicit cast `def` to `boolean false` -> `boolean false`;
|
||
|
boolean and `boolean true` and `boolean false` -> `boolean false`;
|
||
|
implicit cast `boolean false` -> `def`;
|
||
|
store `def` to `y`
|
||
|
|
||
|
[[boolean-or-operator]]
|
||
|
==== Boolean Or
|
||
|
|
||
|
Use the `boolean or operator '||'` to OR together two `boolean` type values
|
||
|
where if either one of the `boolean` type values is `true` the resultant
|
||
|
`boolean` type value is `true` and `false` otherwise.
|
||
|
|
||
|
*Errors*
|
||
|
|
||
|
* If either evaluated value is a value other than a `boolean` type value or
|
||
|
a value that is castable to a `boolean` type value.
|
||
|
|
||
|
*Truth*
|
||
|
|
||
|
[cols="^1,^1,^1"]
|
||
|
|====
|
||
|
| | true | false
|
||
|
| true | true | true
|
||
|
| false | true | false
|
||
|
|====
|
||
|
|
||
|
*Grammar:*
|
||
|
[source,ANTLR4]
|
||
|
----
|
||
|
boolean_and: expression '||' expression;
|
||
|
----
|
||
|
|
||
|
*Examples*
|
||
|
|
||
|
* Boolean or with the `boolean` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> boolean x = false;
|
||
|
<2> boolean y = x || true;
|
||
|
<3> y = false;
|
||
|
<4> y = y || x;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `boolean x`;
|
||
|
store `boolean false` to `x`
|
||
|
<2> declare `boolean y`;
|
||
|
load from `x` -> `boolean false`;
|
||
|
boolean or `boolean false` and `boolean true` -> `boolean true`;
|
||
|
store `boolean true` to `y`
|
||
|
<3> store `boolean false` to `y`
|
||
|
<4> load from `y` -> `boolean false @0`;
|
||
|
load from `x` -> `boolean false @1`;
|
||
|
boolean or `boolean false @0` and `boolean false @1` -> `boolean false`;
|
||
|
store `boolean false` to `y`
|
||
|
+
|
||
|
* Boolean or with the `def` type.
|
||
|
+
|
||
|
[source,Painless]
|
||
|
----
|
||
|
<1> def x = false;
|
||
|
<2> def y = x || true;
|
||
|
<3> y = false;
|
||
|
<4> y = y || x;
|
||
|
----
|
||
|
+
|
||
|
<1> declare `def x`;
|
||
|
implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `x`
|
||
|
<2> declare `def y`;
|
||
|
load from `x` -> `def`;
|
||
|
implicit cast `def` to `boolean false` -> `boolean true`;
|
||
|
boolean or `boolean false` and `boolean true` -> `boolean true`;
|
||
|
implicit cast `boolean true` to `def` -> `def`;
|
||
|
store `def` to `y`
|
||
|
<3> implicit cast `boolean false` to `def` -> `def`;
|
||
|
store `def` to `y`;
|
||
|
<4> load from `y` -> `def`;
|
||
|
implicit cast `def` to `boolean false @0` -> `boolean false @0`;
|
||
|
load from `x` -> `def`;
|
||
|
implicit cast `def` to `boolean false @1` -> `boolean false @1`;
|
||
|
boolean or `boolean false @0` and `boolean false @1` -> `boolean false`;
|
||
|
implicit cast `boolean false` -> `def`;
|
||
|
store `def` to `y`
|