Goal: CompilationUnit
If two single-type-import declarations in the same compilation unit
attempt to import types with the same simple name, then a compile-time
error occurs, unless the two types are the same type, in which case the
duplicate declaration is ignored.
If another type with the same name is otherwise declared in the current
compilation unit except by a type-import-on-demand declaration (§7.5.2),
then a compile-time error occurs.
A compile-time error occurs if the Identifier naming a class or interface appears as the name of any other class type or interface type declared in the same package (§7.6).
A compile-time error occurs if the Identifier naming a class or interface is also declared as a type by a single-type-import declaration (§7.5.1) in the compilation unit (§7.3) containing the class declaration.
PackageDeclaration:
package Name
;
Name is a fully-qualified name
No type declaration and subpackage of the same name.
ImportDeclaration:
SingleTypeImportDeclaration
TypeImportOnDemandDeclaration
SingleTypeImportDeclaration:
import Name
;
Name must be a fully qualified name of a class or interface type that is in an accessible package and declared public.
TypeImportOnDemandDeclaration:
import Name
. * ;
Name must be a name of an accessible package.
Two or more type-import-on-demand declarations in the same compilation unit may name the same package; the effect is as if there were exactly one such declaration. It is not a compile-time error to name the current package or java.lang in a type-import-on-demand declaration, even though they are already imported; the duplicate type-import-on-demand declaration is ignored.
TypeDeclaration:
ClassDeclaration
InterfaceDeclaration
;
Modifiers must be one of: public abstract final
If a class that is not abstract cannot contain abstract methods. A class has abstract methods if any of the following is true:
ClassType must be an accessible, non-final class type.
Cycles in the subclass relation are not allowed.
Interfaces:
implements InterfaceType*
Each InterfaceType must name an accessible (§6.6) interface type.
A compile-time error occurs if the same interface is mentioned two
or more times in a single implements clause.
ClassBody:
{ ClassBodyDeclaration*
}
ClassBodyDeclaration:
ClassMemberDeclaration
StaticInitializer
ConstructorDeclaration
ClassMemberDeclaration:
FieldDeclaration
MethodDeclaration
FieldDeclaration: Modifier* Type VariableDeclarator* ;No duplicate field declarations.
Modifiers can only be: public protected private final static transient
volatile.
final fields must include an initializer.
final fields cannot be assigned.
final fields cannot be volatile.
VariableDeclarator:
VariableDeclaratorId
VariableDeclaratorId
= VariableInitializer
VariableDeclaratorId:
Identifier
VariableDeclaratorId
[ ]
VariableInitializer:
Expression
ArrayInitializer
It is a compile-time error if the evaluation of a variable initializer for a field of a class (or interface) can complete abruptly with a checked exception (§11.2).
The initializer of a class variable occurs in a static context.
A compile-time error occurs if an initialization expression for a class variable contains a use by a simple name of that class variable or of another class variable whose declaration occurs to its right (that is, textually later) in the same class.
A compile-time error occurs if an initialization expression for an instance variable contains a use by a simple name of that instance variable or of another instance variable whose declaration occurs to its right (that is, textually later) in the same class.
It is a compile-time error for the body of a class to have as members two methods with the same signature (§8.4.2) (name, number of parameters, and types of any parameters).
A method that is declared static is called a class method.
A method that is not declared static is called an instance method.
Modifiers can only be: public protected private abstract static
final synchronized native
A compile-time error occurs if a method declaration that contains the
keyword abstract also contains any one of the keywords private, static,
final, native, or synchronized.
A private method and all methods declared in a final class (§8.1.2.2)
are implicitly final, because it is impossible to override them.
It is a compile-time error to attempt to override or hide a final method.
A compile-time error occurs if an instance method overrides a static
method.
A compile-time error occurs if a static method hides an instance method.
If a method declaration overrides or hides the declaration of another method, then a compile-time error occurs if they have different return types or if one has a return type and the other is void. Moreover, a method declaration must not have a throws clause that conflicts (§8.4.4) with that of any method that it overrides or hides; otherwise, a compile-time error occurs.
The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method. In more detail:
Latter production is obsolescent
FormalParameterList:
FormalParameter+
If two formal parameters are declared to have the same name (that is, their declarations mention the same Identifier), then a compile-time error occurs.
FormalParameter:
Type VariableDeclaratorId
Throws:
throws ClassType*
For each checked exception that can result from execution of the body of a method or constructor, a compile-time error occurs unless that exception type or a superclass of that exception type is mentioned in a throws clause in the declaration of the method or constructor.
The body of a class method occurs in a static context.
The body of a method must be a semicolon if and only if the method
is either abstract (§8.4.3.1) or native (§8.4.3.4).
If a method is declared void, then its body must not contain any return
statement (§14.15) that has an Expression.
If a method is declared to have a return type, then every return statement
(§14.15) in its body must have an Expression. A compile-time error
occurs if the body of the method can complete normally (§14.1).
StaticInitializer: static BlockIt is a compile-time error for a static initializer to be able to complete abruptly (§14.1, §15.5) with a checked exception (§11.2).
The static initializers and class variable initializers may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope.
If a return statement (§14.15) appears anywhere within a static initializer, then a compile-time error occurs.
The static initializer occurs in a static context.
Modifiers can only be: public protected private
ConstructorDeclarator:
SimpleName
( FormalParameterListopt )
The SimpleName in the ConstructorDeclarator must be the simple name of the class that contains the constructor declaration; otherwise a compile-time error occurs.
ConstructorBody:
{ ExplicitConstructorInvocationopt
BlockStatementsopt }
It is a compile-time error for a constructor to directly or indirectly invoke itself through a series of one or more explicit constructor invocations involving this.
ExplicitConstructorInvocation:
this ( ArgumentListopt
) ;
super ( ArgumentListopt
) ;
The argument list occurs in a static context.
If no explicit constructor invocation occurs, then the compiler inserts
"super.();"
If no constructor declarations appear in a class, then the compiler
provides an empty constructor that takes no arguments and whose body is
"super.();"
Modifiers can only be: public abstract.
ExtendsInterfaces:
extends InterfaceType*
Each InterfaceType must name an accessible interface type.
A compile-time error occurs if there is a circularity such that an
interface directly or indirectly extends itself.
InterfaceBody:
{ InterfaceMemberDeclaration*
}
InterfaceMemberDeclaration:
ConstantDeclaration
AbstractMethodDeclaration
ConstantDeclaration:
FieldDeclaration
Modifiers can only be: public static final
Java Spec is wrong here - forgot trailing semicolon, and says only
one VariableDeclarator.
Every field in the body of an interface must have an initialization expression, which need not be a constant expression. This initialization expression occurs in a static context, and cannot contain a reference by simple name to the same field or to another field whose declaration occurs textually later in the same interface.
AbstractMethodDeclaration:
MethodHeader ;
Modifiers can only be: public abstract
If a method declaration in an interface overrides the declaration of a method in another interface, a compile-time error occurs if the methods have different return types or if one has a return type and the other is void. Moreover, a method declaration must not have a throws clause that conflicts (§8.4.4) with that of any method that it overrides; otherwise, a compile-time error occurs.
It is possible for an interface to inherit more than one method with the same signature (§8.4.2). Such a situation does not in itself cause a compile-time error. The interface is considered to inherit all the methods. However, a compile-time error occurs if, for any two such inherited methods, either they have different return types or one has a return type and the other is void. (The throws clauses do not cause errors in this case.) [Compare to 8.4.6.4]
ArrayInitializer: { VariableInitializer* ,opt }Each expression must be assignment-compatible (§5.2) with the array's component type.
Modifiers: Modifier Modifiers Modifier Modifier: one of public protected private static abstract final native synchronized transient volatileNo duplicate Modifiers allowed.
BlockStatement:
LocalVariableDeclarationStatement
Statement
LocalVariableDeclarationStatement:
LocalVariableDeclaration
;
LocalVariableDeclaration:
Type VariableDeclarator+
If a declaration of an identifier as a local variable appears within the scope of a parameter or local variable of the same name, a compile-time error occurs.
If a declarator does not have an initialization expression, then a Java compiler must prove, using exactly the algorithm given in §16, that every reference to the variable is necessarily preceded by execution of an assignment to the variable. If this is not the case, then a compile-time error occurs.
Statement:
Block
;
do Statement
while ( Expression ) ;
if ( Expression
) Statement
if ( Expression
) Statement else Statement
while ( Expression
) Statement
break Identifieropt
;
continue Identifieropt
;
ExpressionStatement
SwitchStatement
ReturnStatement
SynchronizedStatement
ThrowStatement
TryStatement
LabeledStatement
ForStatement
The Expression in a if, while or do statement must have type boolean.
If no switch, while, do, or for statement encloses an unlabeled break
or continue statement, a compile-time error occurs.
If no appropriately labeled statement encloses a labeled break or continue
statement, a compile-time error occurs.
LabeledStatement:
Identifier :
Statement
A statement labeled by an identifier must not appear anywhere within another statement labeled by the same identifier.
ExpressionStatement:
StatementExpression
;
The type of the Expression must be char, byte, short, or int.
SwitchBlock: { SwitchBlockStatementGroup* SwitchLabel* } SwitchBlockStatementGroup: SwitchLabel+ BlockStatements SwitchLabel: case ConstantExpression : default :Java Spec ambiguous on wether switch labels are required.
Every case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression. No two of the case constant expressions associated with a switch statement may have the same value. At most one default label may be associated with the same switch statement.
ForInit:
StatementExpression+
LocalVariableDeclaration
ForUpdate:
StatementExpression+
The Expression must have type boolean.
ReturnStatement:
return Expressionopt
;
-- The following may be redundant -- A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value (§8.4), or in the body of a constructor (§8.6). A compile-time error occurs if a return statement appears within a static initializer (§8.5). A return statement with an Expression must be contained in a method declaration that is declared to return a value (§8.4). The Expression must denote a variable or value of some type T that is assignable (§5.2) to the declared result type of the method.
ThrowStatement:
throw Expression
;
The Expression in a throw statement must denote a variable or value
of a reference type which is assignable (§5.2) to the type Throwable.
Moreover, at least one of the following three conditions must be true:
TryStatement:
try Block CatchClause+
try Block
CatchClause* Finally
CatchClause:
catch ( FormalParameter
) Block
The declared type of the exception parameter must be the class Throwable
or a subclass of Throwable. An exception parameter must not have the same
name as a local variable or parameter in whose scope it is declared.
Finally:
finally Block
It is a compile-time error if a statement cannot be executed because it is unreachable. Every Java compiler must carry out the conservative flow analysis specified here to make sure all statements are reachable. See section 14.19
Expression:
Expression ? Expression
: Expression
Expression || Expression
Expression &&
Expression
Expression | Expression
Expression ^ Expression
Expression & Expression
Expression == Expression
Expression != Expression
Expression < Expression
Expression > Expression
Expression <= Expression
Expression >= Expression
Expression instanceof
ReferenceType
Expression << Expression
Expression >> Expression
Expression <<<
Expression
Expression + Expression
Expression - Expression
Expression * Expression
Expression / Expression
Expression % Expression
+ Expression
- Expression
~ Expression
! Expression
StatementExpression
ArrayCreationExpression
Literal
this
FieldAccess
ArrayAccess
Assignment
CastExpression
Name
The argument to the unary + or - or ~ operator must be a primitive numeric type; the result is a value of the unary promoted type of the argument.
The argument to the unary ! operator must be boolean, the result is a boolean value.
The binary operators *, /, %, - are binary numeric operators. The arguments to binary numeric operators must be numeric.Binary numeric promotion is performed on the operands (§5.6.2), and the type of the expression is the promoted type of its operands.
If the type of either operand of a binary + operator is String, then the operation is string concatenation, the other argument is converted to type String (if necessary), and the result is type String. If neither operand of a binary + operator is String, then + is treated as a binary numeric operator (described above).
The arguments to the binary operators >>, <<, >>> must be primitive integral types, the result type is the unary promoted type of the left operand.
The arguments to the a numerical comparison operators (<,<=,>,<=) must be primitive numeric types; the result is always boolean.
The type of a Expression operand of the instanceof operator must be a reference type or the null type. The ReferenceType mentioned after the instanceof operator must denote a reference type. If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, then the instanceof relational expression likewise produces a compile-time error.
The equality operators == and != may be used to compare two operands of numeric type, or two operands of type boolean, or two operands that are each of either reference type or the null type. The type of an equality expression is always boolean. A compile-time error occurs if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.4).
When both operands of an operator &, ^, or | are of primitive integral type, binary numeric promotion is first performed on the operands (§5.6.2). The type of the bitwise operator expression is the promoted type of the operands. When both operands of a &, ^, or | operator are of type boolean, then the type of the bitwise operator expression is boolean. All other cases result in a compile-time error.
The arguments to && and || must be boolean, the result is also boolean.
The keyword this may be used only in a non-static context (the body of an instance method or constructor, or in the initializer of an instance variable of a class). The type of this is the class C within which the keyword this occurs.
The argument to a prefix or postfix increment or decrement operation must be a numeric variable, the result is a value of the same type.
ClassInstanceCreationExpression:
new ClassType
( Expression* )
ClassType must name a class that is not abstract. This class type is
the type of the creation expression.
As in method invocations, a compile-time method matching error results
if there is no most-specific, accessible, applicable constructor.
ArrayCreationExpression:
new
PrimitiveType DimExpr+ Dimsopt
new ClassOrInterfaceType
DimExpr+ Dimsopt
DimExpr:
[ Expression
]
Dims:
[ ]
Dims [ ]
The type of the creation expression is an array type that can denoted
by a copy of the creation expression from which the new keyword and every
has been deleted.
The type of each dimension expression Expression must be an integral type.
FieldAccess:
Primary . Identifier
super . Identifier
The type of the Primary must be a reference type T, which should contain a single accessible member field named Identifier, and the type of the field access expression is a variable of the declared type of of that field. It is a compile-time error to reference instance fields in a static context.
The special form using the keyword super is valid only in a non-static context (an instance method or constructor, or in the initializer of an instance variable of a class), and is equivalent to "((C) this).Identifier", where C denotes the direct superclass of the current class.
MethodInvocation:
Name ( Expression+
)
Primary . Identifier
( Expression+ )
super . Identifier
( Expression+ )
Validity of a MethodInvocation is mostly done by name resolution algorithm.
If the method invocation has, before the left parenthesis, a MethodName of the form Identifier, and the method invocation appears in a static context, then the compile-time declaration of the method must be static.
If the method invocation has, before the left parenthesis, a MethodName of the form TypeName . Identifier, then the compile-time declaration should be static.
If the compile-time declaration for the method invocation is void, then the method invocation must be a top-level expression, that is, the Expression in an expression statement (§14.7) or in the ForInit or ForUpdate part of a for statement (§14.12).
If the compile-time declaration for the method invocation is not void, then the tye of the method invocation expression is the result type specified in the compile-time declaration.
ArrayAccess:
Name [ Expression
]
PrimaryNoNewArray
[ Expression ]
The type of the array reference expression must be an array type T[],
and the type of the array access expression is T.
The index expression undergoes unary numeric promotion (§5.6.1);
the promoted type must be int.
PostfixExpression:
Primary
Name
PostIncrementExpression
PostDecrementExpression
CastExpression:
( PrimitiveType Dimsopt
) UnaryExpression
( Expression ) UnaryExpressionNotPlusMinus
( Name Dims
) UnaryExpressionNotPlusMinus
The type of a cast expression is the type whose name appears within the parentheses. (The parentheses and the type they contain are sometimes called the cast operator.) The result of a cast expression is not a variable, but a value.
Not all casts are permitted by the Java language. Some casts result in an error at compile time. For example, a primitive value may not be cast to a reference type.
ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression
? Expression : ConditionalExpression
The first expression must be of type boolean.
The type of a conditional expression is determined as follows:
The result of the first operand of an assignment operator must be a
variable.
The type of the assignment expression is the type of the variable.
A variable that is declared final cannot be assigned to
For =, a compile-time error occurs if the type of the right-hand operand cannot be converted to the type of the variable by assignment conversion (§5.2).
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
LeftHandSide:
Name
FieldAccess
ArrayAccess
AssignmentOperator: one of
= *= /= %= += -= <<=
>>= >>>= &= ^= |=
ConstantExpression:
Expression
A compile-time constant expression is an expression denoting a value of primitive type or a String that is composed using only the following:
Literals of primitive type and literals of
type String
Casts to primitive types and casts to type
String
The unary operators +, -, ~, and ! (but not
++ or --)
The multiplicative operators *, /, and %
The additive operators + and -
The shift operators <<, >>, and >>>
The relational operators <, <=, >, and
>= (but not instanceof)
The equality operators == and !=
The bitwise and logical operators &, ^,
and |
The conditional-and operator && and
the conditional-or operator ||
The ternary conditional operator ? :
Simple names that refer to final variables
whose initializers are constant expressions
Qualified names of the form TypeName .
Identifier that refer to final variables whose
initializers are constant expressions
PrimitiveType:
NumericType
boolean
NumericType:
IntegralType
FloatingPointType
IntegralType: one of
byte short int long
char
FloatingPointType: one of
float double
ReferenceType:
ClassOrInterfaceType
ArrayType
ClassOrInterfaceType:
Name
The name must resolve to a class or interface type
ClassType:
ClassOrInterfaceType
The name must resolve to a class type
InterfaceType:
ClassOrInterfaceType
The name must resolve to a interface type
ArrayType:
PrimitiveType
[ ]
Name
[ ]
ArrayType
[ ]
Name must be a type name.
Name: SimpleName QualifiedName SimpleName: Identifier QualifiedName: Name . IdentifierNot certain about compile-time errors for this section.
Literal: IntegerLiteral FloatingPointLiteral BooleanLiteral CharacterLiteral StringLiteral NullLiteralInts, longs, and doubles should not be too big.
The type of an integer literal that ends with L or l is long; the type
of any other integer literal is int.
The type of a floating-point literal that ends with F or f is float;
the type of any other floating-point literal is double.
The type of a boolean literal is boolean.
The type of a character literal is char.
The type of a string literal is String.
The type of the null literal null is the null type.