This notional machine represents a source code expression
in the form of a tree.
This makes the structure of the expression explicit,
and it allows visualizing the various steps of expression evaluation.
It also allows annotating the various subexpressions with their types.
An expression tree is essentially an abstract syntax tree (AST),
focused on just an expression.
Here is an example Java expression:
The corresponding expression tree
shows not only the expression’s structure
but also the types and values of all subexpressions:
A notional machine focuses on a subset of the syntax and semantics of a programming language. The following misconceptions are related to the language features expressible in this notional machine.

Addition has higher precedence than string concatenation

Parenthesis are used to access an element in an array

Arrays are created without the new keyword

The number of brackets in an array type or an array initializer corresponds to the length of the array

The type of a multi-dimensional array is written as T[] T[] T[]

To get the length of an array, one needs to call its length method

Array initializers list the elements in square brackets

Array rank and array length are the same thing

= compares two values

An assignment a=b is not an expression

One can invoke a method on primitive values

One needs a variable to invoke a method

Member accesses cannot be chained together

Method calls or field accesses cannot be chained to a constructor invocation

Chained methods are all called on the object at the beginning of the chain

Char is not a numeric type

To test whether an expression evaluates to true or false, one must compare it to a constant

To test whether an expression is True or False, one must compare it to True or to False

To test whether an expression is true or false, one must compare it to true or to false

Expressions that consist of multiple parts have no type

One can write the constructor name, without new, to instantiate a class

Evaluating an expression means outputting its result

An expression that reads a variable also updates its value after the evaluation

One has to evaluate an expression to determine its type

The expression tree of an expression involving a call inlines the call's computation of the returned value

The expression tree of an expression involving a variable inlines the variable's definition

Dividing two integers can produce a rational number

A literal is not an expression

When passing a literal string as argument to a method, no quotes are needed

To map a boolean expression to a boolean, a conditional operator is necessary

To map a boolean expression to a bool, a ternary conditional operator is necessary

A reference variable can point to multiple objects

A variable can contain more than one value

A multi-dimensional array is one thing

Expressions must consist of more than one piece

One cannot invoke methods on String literals

If a variable is at least as big (bit-width) as a value, then no cast is needed to a assign the value to the variable

An object contains only the fields declared in its class

There are no float literals

Smaller types are never automatically converted into bigger ones without an explicit cast

Multi-dimensional arrays have a rectangular shape

There are no long literals

Subclasses inherit fields but not methods

&& and || always evaluate both operands

and/or always evaluate both operands

& is only a bitwise AND

One cannot invoke toString() on a String

NullPointerExceptions are detected at compile time

Numeric types can be coerced to boolean

A variable is needed to instantiate an object

Only the elements of the innermost array of a multi-dimensional array are accessible

Out-of-bounds array elements are null

Nested function calls are invoked outside in

Nested method calls are invoked outside in

() are optional for method calls without arguments

() are optional for function calls without arguments

The type of a primitive variable depends on its value

Private members of a superclass are accessible from a subclass

Rational fractions are literals

Every reference type can be coerced to boolean

One can cast between references and ints

Chained accesses are invoked from right to left

The name self is not an expression

String literals can be in single quotes

One can know the length of a String object by accessing its length field

One needs to call the String constructor to get a String object from a literal

String concatenation stringifies non-String operand expressions

The multiplication operator can repeat a String a number of times

To call a method on a superclass, parentheses are needed after the keyword super

The type of a numerical expression depends on the type expected by the surrounding context

One can assign to this

this can be null

Instance method or constructor call nodes in expression trees have a child labeled "this"

In a constructor, this is null

The name this is not an expression

Invoking toString() prints something

= stores an expression in a variable