This specification is not final and is subject to change. Use is subject to license terms.

Pattern matching for instanceof (Preview)

Changes to the Java® Language Specification • Version 14-internal+0-adhoc.gbierman.20190918

This document describes changes to the Java Language Specification to support pattern matching in instanceof expressions. See JEP 305.

Changes are described with respect to existing sections of the JLS. New text is indicated like this and deleted text is indicated like this. Explanation and discussion, as needed, is set aside in grey boxes.

Chapter 4: Types, Values, and Variables

4.12 Variables

4.12.3 Kinds of Variables

There are eight nine kinds of variables:

  1. A class variable is a field declared using the keyword static within a class declaration (8.3.1.1), or with or without the keyword static within an interface declaration (9.3).

    A class variable is created when its class or interface is prepared (12.3.2) and is initialized to a default value (4.12.5). The class variable effectively ceases to exist when its class or interface is unloaded (12.7).

  2. An instance variable is a field declared within a class declaration without using the keyword static (8.3.1.1).

    If a class T has a field a that is an instance variable, then a new instance variable a is created and initialized to a default value (4.12.5) as part of each newly created object of class T or of any class that is a subclass of T (8.1.4). The instance variable effectively ceases to exist when the object of which it is a field is no longer referenced, after any necessary finalization of the object (12.6) has been completed.

  3. Array components are unnamed variables that are created and initialized to default values (4.12.5) whenever a new object that is an array is created (10, 15.10.2). The array components effectively cease to exist when the array is no longer referenced.

  4. Method parameters (8.4.1) name argument values passed to a method.

    For every parameter declared in a method declaration, a new parameter variable is created each time that method is invoked (15.12). The new variable is initialized with the corresponding argument value from the method invocation. The method parameter effectively ceases to exist when the execution of the body of the method is complete.

  5. Constructor parameters (8.8.1) name argument values passed to a constructor.

    For every parameter declared in a constructor declaration, a new parameter variable is created each time a class instance creation expression (15.9) or explicit constructor invocation (8.8.7) invokes that constructor. The new variable is initialized with the corresponding argument value from the creation expression or constructor invocation. The constructor parameter effectively ceases to exist when the execution of the body of the constructor is complete.

  6. Lambda parameters (15.27.1) name argument values passed to a lambda expression body (15.27.2).

    For every parameter declared in a lambda expression, a new parameter variable is created each time a method implemented by the lambda body is invoked (15.12). The new variable is initialized with the corresponding argument value from the method invocation. The lambda parameter effectively ceases to exist when the execution of the lambda expression body is complete.

  7. An exception parameter is created each time an exception is caught by a catch clause of a try statement (14.20).

    The new variable is initialized with the actual object associated with the exception (11.3, 14.18). The exception parameter effectively ceases to exist when execution of the block associated with the catch clause is complete.

  8. Local variables are declared by local variable declaration statements (14.4).

    Whenever the flow of control enters a block (14.2) or for statement (14.14), a new variable is created for each local variable declared in a local variable declaration statement immediately contained within that block or for statement.

    A local variable declaration statement may contain an expression which initializes the variable. The local variable with an initializing expression is not initialized, however, until the local variable declaration statement that declares it is executed. (The rules of definite assignment (16)(17) prevent the value of a local variable from being used before it has been initialized or otherwise assigned a value.) The local variable effectively ceases to exist when the execution of the block or for statement is complete.

    Were it not for one exceptional situation, a local variable could always be regarded as being created when its local variable declaration statement is executed. The exceptional situation involves the switch statement (14.11), where it is possible for control to enter a block but bypass execution of a local variable declaration statement. Because of the restrictions imposed by the rules of definite assignment (16)(17), however, the local variable declared by such a bypassed local variable declaration statement cannot be used before it has been definitely assigned a value by an assignment expression (15.26).

  1. Pattern variables are declared in patterns. Pattern variables are assigned a value by the process of pattern matching (16.3). This process is conditional; a pattern variable is only assigned a value if the pattern match succeeds. For this reason, pattern variables require special rules restricting their use (6.3).

Example 4.12.3-1. Different Kinds of Variables

This example has been updated to include pattern variables.

4.12.4 final Variables

A variable can be declared final. A final variable may only be assigned to once. It is a compile-time error if a final variable is assigned to unless it is definitely unassigned immediately prior to the assignment ([1617]).

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object. This applies also to arrays, because arrays are objects; if a final variable holds a reference to an array, then the components of the array may be changed by operations on the array, but the variable will always refer to the same array.

A blank final is a final variable whose declaration lacks an initializer.

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (15.28). Whether a variable is a constant variable or not may have implications with respect to class initialization (12.4.1), binary compatibility (13.1), reachability (14.21), and definite assignment ([16.1.117.1.1]).

Three Four kinds of variable are implicitly declared final: a field of an interface (9.3), a local variable declared as a resource of a try-with-resources statement (14.20.3), and an exception parameter of a multi-catch clause (14.20), and a pattern variable (16.1). An exception parameter of a uni-catch clause is never implicitly declared final, but may be effectively final.

Example 4.12.4-1. Final Variables

Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors. In this program:

class Point {
    int x, y;
    int useCount;
    Point(int x, int y) { this.x = x; this.y = y; }
    static final Point origin = new Point(0, 0);
}

the class Point declares a final class variable origin. The origin variable holds a reference to an object that is an instance of class Point whose coordinates are (0, 0). The value of the variable Point.origin can never change, so it always refers to the same Point object, the one created by its initializer. However, an operation on this Point object might change its state - for example, modifying its useCount or even, misleadingly, its x or y coordinate.

Certain variables that are not declared final are instead considered effectively final:

If a variable is effectively final, adding the final modifier to its declaration will not introduce any compile-time errors. Conversely, a local variable or parameter that is declared final in a valid program becomes effectively final if the final modifier is removed.

4.12.5 Initial Values of Variables

Every variable in a program must have a value before its value is used:

Example 4.12.5-1. Initial Values of Variables

class Point {
    static int npoints;
    int x, y;
    Point root;
}

class Test {
    public static void main(String[] args) {
        System.out.println("npoints=" + Point.npoints);
        Point p = new Point();
        System.out.println("p.x=" + p.x + ", p.y=" + p.y);
        System.out.println("p.root=" + p.root);
    }
}

This program prints:

npoints=0
p.x=0, p.y=0
p.root=null

illustrating the default initialization of npoints, which occurs when the class Point is prepared (12.3.2), and the default initialization of x, y, and root, which occurs when a new Point is instantiated. See 12 for a full description of all aspects of loading, linking, and initialization of classes and interfaces, plus a description of the instantiation of classes to make new class instances.

Chapter 6: Names

6.1 Declarations

A declaration introduces an entity into a program and includes an identifier (3.8) that can be used in a name to refer to this entity. The identifier is constrained to be a type identifier when the entity being introduced is a class, interface, or type parameter.

A declared entity is one of the following:

Constructors (8.8) are also introduced by declarations, but use the name of the class in which they are declared rather than introducing a new name.

The declaration of a type which is not generic (class C ...) declares one entity: a non-generic type (C). A non-generic type is not a raw type, despite the syntactic similarity. In contrast, the declaration of a generic type (class C<T> ... or interface C<T> ...) declares two entities: a generic type (C<T>) and a corresponding non-generic type (C). In this case, the meaning of the term C depends on the context where it appears:

The 14 non-generic contexts are as follows:

  1. In a uses or provides directive in a module declaration (7.7.1)

  2. In a single-type-import declaration (7.5.1)

  3. To the left of the . in a single-static-import declaration (7.5.3)

  4. To the left of the . in a static-import-on-demand declaration (7.5.4)

  5. To the left of the ( in a constructor declaration (8.8)

  6. After the @ sign in an annotation (9.7)

  7. To the left of .class in a class literal (15.8.2)

  8. To the left of .this in a qualified this expression (15.8.4)

  9. To the left of .super in a qualified superclass field access expression (15.11.2)

  10. To the left of .Identifier or .super.Identifier in a qualified method invocation expression (15.12)

  11. To the left of .super:: in a method reference expression (15.13)

  12. In a qualified expression name in a postfix expression or a try-with-resources statement (15.14.1, 14.20.3)

  13. In a throws clause of a method or constructor (8.4.6, 8.8.5, 9.4)

  14. In an exception parameter declaration (14.20)

The first eleven non-generic contexts correspond to the first eleven syntactic contexts for a TypeName in 6.5.1. The twelfth non-generic context is where a qualified ExpressionName such as C.x may include a TypeName C to denote static member access. The common use of TypeName in these twelve contexts is significant: it indicates that these contexts involve a less-than-first-class use of a type. In contrast, the thirteenth and fourteenth non-generic contexts employ ClassType, indicating that throws and catch clauses use types in a first-class way, in line with, say, field declarations. The characterization of these two contexts as non-generic is due to the fact that an exception type cannot be parameterized.

Note that the ClassType production allows annotations, so it is possible to annotate the use of a type in a throws or catch clause, whereas the TypeName production disallows annotations, so it is not possible to annotate the name of a type in, say, a single-type-import declaration.

Naming Conventions

The class libraries of the Java SE Platform attempt to use, whenever possible, names chosen according to the conventions presented below. These conventions help to make code more readable and avoid certain kinds of name conflicts.

We recommend these conventions for use in all programs written in the Java programming language. However, these conventions should not be followed slavishly if long-held conventional usage dictates otherwise. So, for example, the sin and cos methods of the class java.lang.Math have mathematically conventional names, even though these method names flout the convention suggested here because they are short and are not verbs.

Package Names and Module Names

Developers should take steps to avoid the possibility of two published packages having the same name by choosing unique package names for packages that are widely distributed. This allows packages to be easily and automatically installed and catalogued. This section specifies a suggested convention for generating such unique package names. Implementations of the Java SE Platform are encouraged to provide automatic support for converting a set of packages from local and casual package names to the unique name format described here.

If unique package names are not used, then package name conflicts may arise far from the point of creation of either of the conflicting packages. This may create a situation that is difficult or impossible for the user or programmer to resolve. The classes ClassLoader and ModuleLayer can be used to isolate packages with the same name from each other in those cases where the packages will have constrained interactions, but not in a way that is transparent to a naïve program.

You form a unique package name by first having (or belonging to an organization that has) an Internet domain name, such as oracle.com. You then reverse this name, component by component, to obtain, in this example, com.oracle, and use this as a prefix for your package names, using a convention developed within your organization to further administer package names. Such a convention might specify that certain package name components be division, department, project, machine, or login names.

Example 6.1-1. Unique Package Names

com.nighthacks.scrabble.dictionary
org.openjdk.compiler.source.tree
net.jcip.annotations
edu.cmu.cs.bovik.cheese
gov.whitehouse.socks.mousefinder

The first component of a unique package name is always written in all-lowercase ASCII letters and should be one of the top level domain names, such as com, edu, gov, mil, net, or org, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166.

In some cases, the Internet domain name may not be a valid package name. Here are some suggested conventions for dealing with these situations:

The name of a module should correspond to the name of its principal exported package. If a module does not have such a package, or if for legacy reasons it must have a name that does not correspond to one of its exported packages, then its name should still start with the reversed form of an Internet domain with which its author is associated.

Example 6.1-2. Unique Module Names

com.nighthacks.scrabble
org.openjdk.compiler
net.jcip.annotations

The first component of a package or module name must not be the identifier java. Package and module names that start with the identifier java are reserved for packages and modules of the Java SE Platform.

The name of a package or module is not meant to imply where the package or module is stored on the Internet. For example, a package named edu.cmu.cs.bovik.cheese is not necessarily obtainable from the host cmu.edu or cs.cmu.edu or bovik.cs.cmu.edu. The suggested convention for generating unique package and module names is merely a way to piggyback a package and module naming convention on top of an existing, widely known unique name registry instead of having to create a separate registry for package and module names.

Class and Interface Type Names

Names of class types should be descriptive nouns or noun phrases, not overly long, in mixed case with the first letter of each word capitalized.

Example 6.1-3. Descriptive Class Names

`ClassLoader`
SecurityManager
`Thread`
Dictionary
BufferedInputStream

Likewise, names of interface types should be short and descriptive, not overly long, in mixed case with the first letter of each word capitalized. The name may be a descriptive noun or noun phrase, which is appropriate when an interface is used as if it were an abstract superclass, such as interfaces java.io.DataInput and java.io.DataOutput; or it may be an adjective describing a behavior, as for the interfaces Runnable and Cloneable.

Type Variable Names

Type variable names should be pithy (single character if possible) yet evocative, and should not include lower case letters. This makes it easy to distinguish type parameters from ordinary classes and interfaces.

Container types should use the name E for their element type. Maps should use K for the type of their keys and V for the type of their values. The name X should be used for arbitrary exception types. We use T for type, whenever there is not anything more specific about the type to distinguish it. (This is often the case in generic methods.)

If there are multiple type parameters that denote arbitrary types, one should use letters that neighbor T in the alphabet, such as S. Alternately, it is acceptable to use numeric subscripts (e.g., T1, T2) to distinguish among the different type variables. In such cases, all the variables with the same prefix should be subscripted.

If a generic method appears inside a generic class, it is a good idea to avoid using the same names for the type parameters of the method and class, to avoid confusion. The same applies to nested generic classes.

Example 6.1-4. Conventional Type Variable Names

When type parameters do not fall conveniently into one of the categories mentioned, names should be chosen to be as meaningful as possible within the confines of a single letter. The names mentioned above (E, K, V, X, T) should not be used for type parameters that do not fall into the designated categories.

Method Names

Method names should be verbs or verb phrases, in mixed case, with the first letter lowercase and the first letter of any subsequent words capitalized. Here are some additional specific conventions for method names:

Whenever possible and appropriate, basing the names of methods in a new class on names in an existing class that is similar, especially a class from the Java SE Platform API, will make it easier to use.

Field Names

Names of fields that are not final should be in mixed case with a lowercase first letter and the first letters of subsequent words capitalized. Note that well-designed classes have very few public or protected fields, except for fields that are constants (static final fields).

Fields should have names that are nouns, noun phrases, or abbreviations for nouns.

Examples of this convention are the fields buf, pos, and count of the class java.io.ByteArrayInputStream and the field bytesTransferred of the class java.io.InterruptedIOException.

Constant Names

The names of constants in interface types should be, and final variables of class types may conventionally be, a sequence of one or more words, acronyms, or abbreviations, all uppercase, with components separated by underscore "_" characters. Constant names should be descriptive and not unnecessarily abbreviated. Conventionally they may be any appropriate part of speech.

Examples of names for constants include MIN_VALUE, MAX_VALUE, MIN_RADIX, and MAX_RADIX of the class Character.

A group of constants that represent alternative values of a set, or, less frequently, masking bits in an integer value, are sometimes usefully specified with a common acronym as a name prefix.

For example:

interface ProcessStates {
    int PS_RUNNING   = 0;
    int PS_SUSPENDED = 1;
}

Local Variable and Parameter Names

Local variable and parameter names should be short, yet meaningful. They are often short sequences of lowercase letters that are not words, such as:

One-character local variable or parameter names should be avoided, except for temporary and looping variables, or where a variable holds an undistinguished value of a type. Conventional one-character names are:

Local variable or parameter names that consist of only two or three lowercase letters should not conflict with the initial country codes and domain names that are the first component of unique package names.

6.3 Scope of a Declaration

The scope of a declaration is the region of the program within which the entity declared by the declaration can be referred to using a simple name, provided it is not shadowed (6.4.1).

A declaration is said to be in scope at a particular point in a program if and only if the declaration's scope includes that point.

The scope of the declaration of an observable top level package (7.4.3) is all observable compilation units associated with modules to which the package is uniquely visible (7.4.3).

The declaration of a package that is not observable is never in scope.

The declaration of a subpackage is never in scope.

The package java is always in scope.

The scope of a type imported by a single-type-import declaration (7.5.1) or a type-import-on-demand declaration (7.5.2) is the module declaration (7.7) and all the class and interface type declarations (7.6) of the compilation unit in which the import declaration appears, as well as any annotations on the module declaration or package declaration of the compilation unit.

The scope of a member imported by a single-static-import declaration (7.5.3) or a static-import-on-demand declaration (7.5.4) is the module declaration and all the class and interface type declarations of the compilation unit in which the import declaration appears, as well as any annotations on the module declaration or package declaration of the compilation unit.

The scope of a top level type (7.6) is all type declarations in the package in which the top level type is declared.

The scope of a declaration of a member m declared in or inherited by a class type C (8.1.6) is the entire body of C, including any nested type declarations.

The scope of a declaration of a member m declared in or inherited by an interface type I (9.1.4) is the entire body of I, including any nested type declarations.

The scope of an enum constant C declared in an enum type T is the body of T, and any case label of a switch statement whose expression is of enum type T (14.11).

The scope of a formal parameter of a method (8.4.1), constructor (8.8.1), or lambda expression (15.27) is the entire body of the method, constructor, or lambda expression.

The scope of a class's type parameter (8.1.2) is the type parameter section of the class declaration, the type parameter section of any superclass or superinterface of the class declaration, and the class body.

The scope of an interface's type parameter (9.1.2) is the type parameter section of the interface declaration, the type parameter section of any superinterface of the interface declaration, and the interface body.

The scope of a method's type parameter (8.4.4) is the entire declaration of the method, including the type parameter section, but excluding the method modifiers.

The scope of a constructor's type parameter (8.8.4) is the entire declaration of the constructor, including the type parameter section, but excluding the constructor modifiers.

The scope of a local class declaration immediately enclosed by a block (14.2) is the rest of the immediately enclosing block, including its own class declaration.

The scope of a local class declaration immediately enclosed by a switch block statement group (14.11) is the rest of the immediately enclosing switch block statement group, including its own class declaration.

The scope of a local variable declaration in a block (14.4) is the rest of the block in which the declaration appears, starting with its own initializer and including any further declarators to the right in the local variable declaration statement.

The scope of a local variable declared in the ForInit part of a basic for statement (14.14.1) includes all of the following:

The scope of a local variable declared in the FormalParameter part of an enhanced for statement (14.14.2) is the contained Statement.

The scope of a parameter of an exception handler that is declared in a catch clause of a try statement (14.20) is the entire block associated with the catch.

The scope of a variable declared in the ResourceSpecification of a try-with-resources statement (14.20.3) is from the declaration rightward over the remainder of the ResourceSpecification and the entire try block associated with the try-with-resources statement.

The translation of a try-with-resources statement implies the rule above.

Example 6.3-1. Scope of Type Declarations

These rules imply that declarations of class and interface types need not appear before uses of the types. In the following program, the use of PointList in class Point is valid, because the scope of the class declaration PointList includes both class Point and class PointList, as well as any other type declarations in other compilation units of package points.

Example 6.3-2. Scope of Local Variable Declarations

The following program causes a compile-time error because the initialization of local variable x is within the scope of the declaration of local variable x, but the local variable x does not yet have a value and cannot be used. The field x has a value of 0 (assigned when Test1 was initialized) but is a red herring since it is shadowed (6.4.1) by the local variable x.

The following program does compile:

because the local variable x is definitely assigned (16)(17) before it is used. It prints:

4

In the following program, the initializer for three can correctly refer to the variable two declared in an earlier declarator, and the method invocation in the next line can correctly refer to the variable three declared earlier in the block.

This program produces the output:

2+1=3

A variable declared in a pattern is known as a pattern variable (Chapter 16). Pattern variables differ from other local variables in that they can only be assigned a value by pattern matching (16.3). This process is conditional; a pattern variable is only assigned a value if the pattern match succeeds.

Accordingly the scope of pattern variables is carefully defined so that a pattern variable is only in scope at those program points where pattern matching will have succeeded and the pattern variable will have been definitely assigned a value. Put another way, accessing a pattern variable where pattern matching can not be guaranteed to have succeeded is not possible and will result in a compile-time error.

In this sense, the scope of a pattern variable is a flow dependent concept similar to definite assignment (Chapter 16). The rules that are defined in the rest of this section deliberately have a similar form to those used in Chapter 16.

The scope of a pattern variable is determined by considering the innermost enclosing statement S that contains the pattern variable declaration. The overall scope of a pattern variable V is defined to be (i) those expressions and statements contained in S where V is definitely matched; and (ii) if S is immediately contained by a statement Q, those statements following S contained by Q where V is definitely matched; and (iii) if S is immediately contained by a block, those statements following S contained by that block where V is definitely matched.

The remainder of this section is devoted to a precise explanation of the words "definitely matched at", for which we define three auxiliary technical terms:

The analysis takes into account the structure of statements and expressions, with a special treatment for the boolean expression operators and certain statement forms.

The simplest example is that the pattern variable s is introduced by the expression a instanceof String s when true. In other words, if the value of the expression is true then the pattern matching must have succeeded, and thus the pattern variable must have been assigned a value.

In contrast, the pattern variable t is introduced by the expression !(b instanceof Integer t) when false. This is because the pattern matching could only have succeeded if the value of the expression is false.

Pattern variables can, in certain circumstances, be introduced by a statement. Further details are given in 6.3.2.

6.3.1 Pattern Declaration Scopes and Expressions

Only certain boolean expressions can introduce a new pattern variable into scope. If an expression is not a logical complement expression, conditional-and expression, conditional-or expression, conditional expression, or instanceof operator, then no rules apply regarding the introduction of pattern variables.

6.3.1.1 Conditional-And Operator &&

The following rules apply to a conditional-and expression (15.23):

The first rule rules out the possibility of a pattern variable being implicitly assigned a value more than once by pattern matching. Pattern variables are implicitly final by design.

The second rule means that a pattern variable introduced by the left-hand operand of a conditional-and operator is in scope, and can therefore be used, in the right-hand operand. This allows for expressions such as x instanceof String s && s.length()>0.

6.3.1.2 Conditional-Or Operator ||

The following rules apply to a conditional-or expression (15.24):

6.3.1.3 Logical Complement Operator !

The following rules apply to a logical complement expression (15.15.6):

6.3.1.4 Conditional Operator ? :

The following rules apply to a conditional expression a ? b : c (15.25):

6.3.1.5 instanceof Operator

The following rule applies to an instanceof expression (15.20.2):

Note that no pattern variable is introduced by an expression a instanceof p when false.

6.3.2 Pattern Declaration Scopes and Statements

Only a few statements play a significant role in determining the scope of pattern variables.

The scope of pattern variables declared in subexpressions contained within if, while, do, and for statements can, in certain circumstances, include other contained substatements. Here is an example:

In certain constrained circumstances, a pattern variable can be introduced by a statement. In this case, the pattern variable is in scope at following statements in the enclosing block. Here is an example:

6.3.2.1 Blocks

The following rule applies to a block statement S contained in a block that is not a switch block:

6.3.2.2 if Statements

The following rules apply to a statement if (e) S (14.9.1):

The second rule makes use of the notion of 'cannot complete normally' (14.21), which itself makes use of the concept of a constant expression (15.29). This means that calculating the scope of a pattern variable may require determining whether a simple name, or a qualified name of the form TypeName. Identifier, refers to a constant variable. As pattern variables can never refer to a constant variable, there is no circularity.

The following rules apply to a statement if (e) S else T (14.9.2):

These rules highlight the flow-like nature of scoping for pattern variables. In the following statement:

The pattern variable s is introduced by the instanceof operator and is in scope in the first contained statement (the one before the else keyword), but it is not in scope in the second contained statement (the one after the else keyword).

Moreover, combined with the treatment for the boolean expressions, the scope of pattern variables is robust against code refactorings that exploit the familar boolean logical equivalences. For example, the previous code can be rewritten as:

And, furthermore, can be rewritten as:

6.3.2.3 while Statements

The following rules apply to a statement while (e) S (14.12):

6.3.2.4 do Statements

The following rule applies to a statement do S while (e) (14.13):

6.3.2.5 for Statements

The following rules cover the basic for statement (14.14.1). Since the enhanced for statement (14.14.2) is defined by translation to a basic for statement, no special rules need to be provided for it.

6.3.2.6 switch Statements

The following rule covers the switch statement (14.11).

6.4 Shadowing and Obscuring

A local variable (14.4), formal parameter (8.4.1, 15.27.1), exception parameter (14.20), and local class (14.3), and pattern variable (16) can only be referred to using a simple name, not a qualified name (6.2).

Some declarations are not permitted within the scope of a local variable, pattern variable, formal parameter, exception parameter, or local class declaration because it would be impossible to distinguish between the declared entities using only simple names.

For example, if the name of a formal parameter of a method could be redeclared as the name of a local variable in the method body, then the local variable would shadow the formal parameter and there would be no way to refer to the formal parameter - an undesirable outcome.

It is a compile-time error if the name of a formal parameter is used to declare a new variable within the body of the method, constructor, or lambda expression, unless the new variable is declared within a class declaration contained by the method, constructor, or lambda expression.

It is a compile-time error if the name of a local variable v is used to declare a new variable within the scope of v, unless the new variable is declared within a class whose declaration is within the scope of v.

It is a compile-time error if the name of an exception parameter is used to declare a new variable within the Block of the catch clause, unless the new variable is declared within a class declaration contained by the Block of the catch clause.

It is a compile-time error if the name of a local class C is used to declare a new local class within the scope of C, unless the new local class is declared within another class whose declaration is within the scope of C.

These rules allow redeclaration of a variable or local class in nested class declarations that occur in the scope of the variable or local class; such nested class declarations may be local classes (14.3) or anonymous classes (15.9). Thus, the declaration of a formal parameter, local variable, pattern variable, or local class may be shadowed in a class declaration nested within a method, constructor, or lambda expression; and the declaration of an exception parameter may be shadowed in a class declaration nested within the Block of the catch clause.

There are two design alternatives for handling name clashes created by lambda parameters and other variables declared in lambda expressions. One is to mimic class declarations: like local classes, lambda expressions introduce a new "level" for names, and all variable names outside the expression can be redeclared. Another is a "local" strategy: like catch clauses, for loops, and blocks, lambda expressions operate at the same "level" as the enclosing context, and local variables outside the expression cannot be shadowed. The above rules use the local strategy; there is no special dispensation that allows a variable declared in a lambda expression to shadow a variable declared in an enclosing method.

Note that the rule for local classes does not make an exception for a class of the same name declared within the local class itself. However, this case is prohibited by a separate rule: a class cannot have the same name as a class that encloses it (8.1).

Example 6.4-1. Attempted Shadowing Of A Local Variable

Because a declaration of an identifier as a local variable of a method, constructor, or initializer block must not appear within the scope of a parameter, or local variable, or pattern variable of the same name, a compile-time error occurs for the following program:

This restriction helps to detect some otherwise very obscure bugs. A similar restriction on shadowing of members by local variables was judged impractical, because the addition of a member in a superclass could cause subclasses to have to rename local variables. Related considerations make restrictions on shadowing of local variables by members of nested classes, or on shadowing of local variables by local variables declared within nested classes unattractive as well.

Hence, the following program compiles without error:

On the other hand, local variables with the same name may be declared in two separate blocks or for statements, neither of which contains the other:

This program compiles without error and, when executed, produces the output:

0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1

6.4.1 Shadowing

Some declarations may be shadowed in part of their scope by another declaration of the same name, in which case a simple name cannot be used to refer to the declared entity.

Shadowing is distinct from hiding (8.3, 8.4.8.2, 8.5, 9.3, 9.5), which applies only to members which would otherwise be inherited but are not because of a declaration in a subclass. Shadowing is also distinct from obscuring (6.4.2).

A declaration d of a type named n shadows the declarations of any other types named n that are in scope at the point where d occurs throughout the scope of d.

A declaration d of a field or formal parameter named n shadows, throughout the scope of d, the declarations of any other variables named n that are in scope at the point where d occurs.

A declaration d of a local variable, pattern variable, or exception parameter named n shadows, throughout the scope of d, (a) the declarations of any other fields named n that are in scope at the point where d occurs, and (b) the declarations of any other variables named n that are in scope at the point where d occurs but are not declared in the innermost class in which d is declared.

A declaration d of a method named n shadows the declarations of any other methods named n that are in an enclosing scope at the point where d occurs throughout the scope of d.

A package declaration never shadows any other declaration.

A type-import-on-demand declaration never causes any other declaration to be shadowed.

A static-import-on-demand declaration never causes any other declaration to be shadowed.

A single-type-import declaration d in a compilation unit c of package p that imports a type named n shadows, throughout c, the declarations of:

A single-static-import declaration d in a compilation unit c of package p that imports a field named n shadows the declaration of any static field named n imported by a static-import-on-demand declaration in c, throughout c.

A single-static-import declaration d in a compilation unit c of package p that imports a method named n with signature s shadows the declaration of any static method named n with signature s imported by a static-import-on-demand declaration in c, throughout c.

A single-static-import declaration d in a compilation unit c of package p that imports a type named n shadows, throughout c, the declarations of:

Example 6.4.1-1. Shadowing of a Field Declaration by a Local Variable Declaration

This program produces the output:

x=0, Test.x=1

This program declares:

Since the scope of a class variable includes the entire body of the class (8.2), the class variable x would normally be available throughout the entire body of the method main. In this example, however, the class variable x is shadowed within the body of the method main by the declaration of the local variable x.

A local variable has as its scope the rest of the block in which it is declared (6.3); in this case this is the rest of the body of the main method, namely its initializer "0" and the invocations of System.out.print and System.out.println.

This means that:

The keyword this can also be used to access a shadowed field x, using the form this.x. Indeed, this idiom typically appears in constructors (8.8):

Here, the constructor takes parameters having the same names as the fields to be initialized. This is simpler than having to invent different names for the parameters and is not too confusing in this stylized context. In general, however, it is considered poor style to have local variables with the same names as fields.

Example 6.4.1-2. Shadowing of a Type Declaration by Another Type Declaration

The program compiles and prints:

1

using the class Vector declared here in preference to the generic class java.util.Vector (8.1.2) that might be imported on demand.

6.4.2 Obscuring

A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type, or a package. In these situations, the rules of 6.5.2 specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package. Thus, it is may sometimes be impossible to refer to a type or package via its simple name, even though its declaration is in scope and not shadowed. We say that such a declaration is obscured.

Obscuring is distinct from shadowing (6.4.1) and hiding (8.3, 8.4.8.2, 8.5, 9.3, 9.5).

There is no obscuring between the name of a module and the name of a variable, type, or package; thus, modules may share names with variables, types, and packages, though it is not necessarily recommended to name a module after a package it contains.

The naming conventions of 6.1 help reduce obscuring, but if it does occur, here are some notes about what you can do to avoid it.

When package names occur in expressions:

The first component of a package name is normally not easily mistaken for a type name, as a type name normally begins with a single uppercase letter. (The Java programming language does not actually rely on case distinctions to determine whether a name is a package name or a type name.)

Obscuring involving class and interface type names is rare. Names of fields, parameters, and local variables normally do not obscure type names because they conventionally begin with a lowercase letter whereas type names conventionally begin with an uppercase letter.

Method names cannot obscure or be obscured by other names (6.5.7).

Obscuring involving field names is rare; however:

Obscuring involving constant names is rare:

6.5 Determining the Meaning of a Name

6.5.1 Syntactic Classification of a Name According to Context

A name is syntactically classified as a ModuleName in these contexts:

A name is syntactically classified as a PackageName in these contexts:

A name is syntactically classified as a TypeName in these contexts:

The extraction of a TypeName from the identifiers of a ReferenceType in the 16 contexts above is intended to apply recursively to all sub-terms of the ReferenceType, such as its element type and any type arguments.

For example, suppose a field declaration uses the type p.q.Foo[]. The brackets of the array type are ignored, and the term p.q.Foo is extracted as a dotted sequence of Identifiers to the left of the brackets in an array type, and classified as a TypeName. A later step determines which of p, q, and Foo is a type name or a package name.

As another example, suppose a cast operator uses the type p.q.Foo<? extends String>. The term p.q.Foo is again extracted as a dotted sequence of Identifier terms, this time to the left of the < in a parameterized type, and classified as a TypeName. The term String is extracted as an Identifier in an extends clause of a wildcard type argument of a parameterized type, and classified as a TypeName.

A name is syntactically classified as an ExpressionName in these contexts:

A name is syntactically classified as a MethodName in this context:

A name is syntactically classified as a PackageOrTypeName in these contexts:

A name is syntactically classified as an AmbiguousName in these contexts:

The effect of syntactic classification is to restrict certain kinds of entities to certain parts of expressions:

6.5.2 Reclassification of Contextually Ambiguous Names

An AmbiguousName is then reclassified as follows.

If the AmbiguousName is a simple name, consisting of a single Identifier:

If the AmbiguousName is a qualified name, consisting of a name, a ".", and an Identifier, then the name to the left of the "." is first reclassified, for it is itself an AmbiguousName. There is then a choice:

The requirement that a potential type name be "a valid TypeIdentifier" prevents treating var as a type name. It is usually redundant, because the rules for declarations already prevent the introduction of types named var. However, in some cases, a compiler may find a binary class named var, and we want to be clear that such classes can never be named. The simplest solution is to consistently check for a valid TypeIdentifier.

Example 6.5.2-1. Reclassification of Contextually Ambiguous Names

Consider the following contrived "library code":

and then consider this example code in another package:

First of all, the name org.rpgpoet.Music.wizards.length is classified as an ExpressionName because it functions as a PostfixExpression. Therefore, each of the names:

is initially classified as an AmbiguousName. These are then reclassified:

6.5.6 Meaning of Expression Names

6.5.6.1 Simple Expression Names

If an expression name consists of a single Identifier, then there must be exactly one declaration denoting either a local variable, formal parameter, or field in scope at the point at which the Identifier occurs. Otherwise, a compile-time error occurs.

If the declaration denotes an instance variable (8.3.1.1), the expression name must appear within an instance method (8.4.3.2), instance variable initializer (8.3.2), instance initializer (8.6), or constructor (8.8). If the expression name appears within a class method, class variable initializer, or static initializer (8.7), then a compile-time error occurs.

If the declaration declares a final variable which is definitely assigned before the simple expression, the meaning of the name is the value of that variable. Otherwise, the meaning of the expression name is the variable declared by the declaration.

If the expression name appears in an assignment context, invocation context, or casting context, then the type of the expression name is the declared type of the field, local variable, pattern variable, or parameter after capture conversion (5.1.10).

Otherwise, the type of the expression name is the declared type of the field, local variable, pattern variable, or parameter.

That is, if the expression name appears "on the right hand side", its type is subject to capture conversion. If the expression name is a variable that appears "on the left hand side", its type is not subject to capture conversion.

Example 6.5.6.1-1. Simple Expression Names

In this program, the names used as the left-hand-sides in the assignments to i, v, and f denote the local variable i, the field v, and the value of f (not the variable f, because f is a final variable). The example therefore produces an error at compile time because the last assignment does not have a variable as its left-hand side. If the erroneous assignment is removed, the modified code can be compiled and it will produce the output:

1 2 3

Chapter 15: Expressions

15.20 Relational Operators

The numerical comparison operators <, >, <=, and >=, and the instanceof operator, are called the relational operators.

RelationalExpression:
ShiftExpression
RelationalExpression < ShiftExpression
RelationalExpression > ShiftExpression
RelationalExpression <= ShiftExpression
RelationalExpression >= ShiftExpression
RelationalExpression instanceof ReferenceType Pattern

Patterns are defined in Chapter 16.

The relational operators are syntactically left-associative (they group left-to-right).

However, this fact is not useful. For example, a<b<c parses as (a<b)<c, which is always a compile-time error, because the type of a<b is always boolean and < is not an operator on boolean values.

The type of a relational expression is always boolean.

15.20.2 Type Comparison Operator instanceof The instanceof Operator

This subsection has a new title.

The type of the RelationalExpression operand of the instanceof operator must be a reference type or the null type, or a compile-time error occurs.

The RelationalExpression operand of the instanceof operator must be compatible with the Pattern operand as defined in 16.3; otherwise, a compile-time error occurs.

It is a compile-time error if the ReferenceType mentioned after the instanceof operator does not denote a reference type that is reifiable (4.7).

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error (15.16), then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

An instanceof expression matches the value of the RelationalExpression against the Pattern.

The RelationalExpression operand of the instanceof operator must be compatible with the Pattern operand as defined in 16.2; otherwise, a compile-time error occurs.

It is a compile-time error if the type of the Pattern mentioned after the instanceof operator as defined in 16.1 does not denote a reference type that is reifiable (4.7).

At run time, the value of the RelationalExpression is matched against the Pattern, as detailed in 16.3. If it matches then the result of the instanceof operator is true, otherwise the result of the instanceof operator is false

Example 15.20.2-1. The instanceof Operator

This program results in two compile-time errors. The cast (Point)e is incorrect because no instance of Element or any of its possible subclasses (none are shown here) could possibly be an instance of any subclass of Point. The instanceof expression is incorrect for exactly the same reason. If, on the other hand, the class Point were a subclass of Element (an admittedly strange notion in this example):

then the cast would be possible, though it would require a run-time check, and the instanceof expression would then be sensible and valid. The cast (Point)e would never raise an exception because it would not be executed if the value of e could not correctly be cast to type Point.

Chapter 16 Patterns

This is a new Chapter. The current Chapters 16-19 will be renumbered correspondingly as Chapters 17-20.

A pattern describes the shape of data. Pattern matching is the process of comparing a value against a pattern and determining whether the value matches the pattern or not. A pattern may in addition declare a pattern variable to name a component of the shape. If a value matches against a pattern, then this variable is assigned a value by the process of pattern matching. The treatment of scoping of pattern variables in 6.3.1 ensures that pattern variables are only in scope where matching is guaranteed to have succeeded and hence the pattern variable will be bound with a value at run-time.

16.1 Kinds of Patterns

Pattern:
TypeTestPattern

16.1.1 Type Test Pattern

TypeTestPattern:
ReferenceType
ReferenceType Identifier

A type test pattern consists of either a type, or a type and a pattern variable. In both cases, it is a compile-time error if the type does not denote a reference type that is reifiable (4.7).

A type test pattern without an Identifier is called an anonymous type test pattern.

The type of a type test pattern is the ReferenceType.

A type test pattern that is not an anonymous type test pattern is said to declare the pattern variable Identifier. The scope of that pattern variable Identifier is conditional on the context, as defined in 6.3. The type of the pattern variable Identifier is defined to be ReferenceType.

16.2 Compatibility of an Expression with a Pattern

At compile time we check that an expression is compatible with a pattern.

The rules for compatibility are as follows:

16.3 Execution of Pattern Matching

At run time, a value is matched against a pattern. If the value matches the pattern, then additionally values may be assigned to any pattern variables declared in the pattern. The rules for determining whether a value matches a pattern (or not) are as follows:

All other possibilities are excluded by the compile time type-checking of pattern matching.