Class Instance Creation Expressions

Một phần của tài liệu Java SE 8 edition for everyone Java SE 8 edition for everyone Java SE 8 edtion for everyone (Trang 498 - 508)

If a parenthesized expression appears in a context of a particular kind with target type T (§5 (Conversions and Contexts)), its contained expression similarly appears in a context of the same kind with target type T.

If the contained expression is a poly expression (§15.2), the parenthesized expression is also a poly expression. Otherwise, it is a standalone expression.

15.9 Class Instance Creation Expressions

A class instance creation expression is used to create new objects that are instances of classes.

ClassInstanceCreationExpression:

new [TypeArguments] {Annotation} Identifier

[TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]

ExpressionName .new [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]

Primary .new [TypeArguments] {Annotation} Identifier

[TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]

TypeArgumentsOrDiamond:

TypeArguments

<>

The following production from §15.12 is shown here for convenience:

ArgumentList:

Expression {, Expression}

A class instance creation expression specifies a class to be instantiated, possibly followed by type arguments (§4.5.1) or a diamond (<>) if the class being instantiated is generic (§8.1.2), followed by (a possibly empty) list of actual value arguments to the constructor.

If the type argument list to the class is empty — the diamond form <> — the type arguments of the class are inferred. It is legal, though strongly discouraged as a matter of style, to have white space between the "<" and ">" of a diamond.

If the constructor is generic (§8.8.4), the type arguments to the constructor may similarly either be inferred or passed explicitly. If passed explicitly, the type arguments to the constructor immediately follow the keyword new.

EXPRESSIONS Class Instance Creation Expressions 15.9

It is a compile-time error if a class instance creation expression provides type arguments to a constructor but uses the diamond form for type arguments to the class.

This rule is introduced because inference of a generic class's type arguments may influence the constraints on a generic constructor's type arguments.

If TypeArguments is present between new and Identifier, or between Identifier and

(, then it is a compile-time error if any of the type arguments are wildcards (§4.5.1).

The exception types that a class instance creation expression can throw are specified in §11.2.1.

Class instance creation expressions have two forms:

Unqualified class instance creation expressions begin with the keyword new. An unqualified class instance creation expression may be used to create an instance of a class, regardless of whether the class is a top level (§7.6), member (§8.5, §9.5), local (§14.3), or anonymous class (§15.9.5).

Qualified class instance creation expressions begin with a Primary expression or an ExpressionName.

A qualified class instance creation expression enables the creation of instances of inner member classes and their anonymous subclasses.

Both unqualified and qualified class instance creation expressions may optionally end with a class body. Such a class instance creation expression declares an anonymous class (§15.9.5) and creates an instance of it.

A class instance creation expression is a poly expression (§15.2) if it uses the diamond form for type arguments to the class, and it appears in an assignment context or an invocation context (§5.2, §5.3). Otherwise, it is a standalone expression.

We say that a class is instantiated when an instance of the class is created by a class instance creation expression. Class instantiation involves determining the class to be instantiated (§15.9.1), the enclosing instances (if any) of the newly created instance (§15.9.2), and the constructor to be invoked to create the new instance (§15.9.3).

15.9.1 Determining the Class being Instantiated

If the class instance creation expression ends in a class body, then the class being instantiated is an anonymous class. Then:

15.9 Class Instance Creation Expressions EXPRESSIONS

• If the class instance creation expression is unqualified:

The Identifier after the new token must denote a class that is accessible, non-

final, and not an enum type; or denote an interface that is accessible. Otherwise a compile-time error occurs.

If TypeArgumentsOrDiamond is present after the Identifier, and denotes <>, then a compile-time error occurs

Let T be the type denoted by Identifier [TypeArgumentsOrDiamond] after the

new token. If TypeArguments is present after the Identifier, then T must denote a well-formed parameterized type (§4.5), or a compile-time error occurs.

If T denotes a class, then an anonymous direct subclass of T is declared. If

T denotes an interface, then an anonymous direct subclass of Object that implements T is declared. In either case, the body of the subclass is the ClassBody given in the class instance creation expression.

The class being instantiated is the anonymous subclass.

• If the class instance creation expression is qualified:

The Identifier after the new token must unambiguously denote an inner class that is accessible, non-final, not an enum type, and a member of the compile-time type of the Primary expression or the ExpressionName. Otherwise, a compile- time error occurs.

If TypeArgumentsOrDiamond is present after the Identifier, and denotes <>, then a compile-time error occurs.

Let T be the type denoted by Identifier [TypeArgumentsOrDiamond] after the

new token. If TypeArguments is present after the Identifier, then T must denote a well-formed parameterized type, or a compile-time error occurs.

An anonymous direct subclass of T is declared. The body of the subclass is the ClassBody given in the class instance creation expression.

The class being instantiated is the anonymous subclass.

If a class instance creation expression does not declare an anonymous class, then:

• If the class instance creation expression is unqualified:

The Identifier after the new token must denote a class that is accessible, non-

abstract, and not an enum type. Otherwise, a compile-time error occurs.

It TypeArgumentsOrDiamond is present after the Identifier, and denotes <>, and the class denoted by Identifier is not generic, then a compile-time error occurs.

EXPRESSIONS Class Instance Creation Expressions 15.9

Let T be the type denoted by Identifier [TypeArgumentsOrDiamond] after the

new token. If TypeArguments is present after the Identifier, then T must denote a well-formed parameterized type, or a compile-time error occurs.

The class being instantiated is the class denoted by Identifier.

• If the class instance creation expression is qualified:

The Identifier after the new token must unambiguously denote an inner class that is accessible, non-abstract, not an enum type, and a member of the compile- time type of the Primary expression or the ExpressionName.

If TypeArgumentsOrDiamond is present after the Identifier, and denotes <>, and the class denoted by Identifier is not generic, then a compile-time error occurs.

Let T be the type denoted by Identifier [TypeArgumentsOrDiamond] after the

new token. If TypeArguments is present after the Identifier, then T must denote a well-formed parameterized type, or a compile-time error occurs.

The class being instantiated is the class denoted by Identifier.

15.9.2 Determining Enclosing Instances

Let C be the class being instantiated, and let i be the instance being created. If

C is an inner class, then i may have an immediately enclosing instance (§8.1.3), determined as follows:

• If C is an anonymous class, then:

– If the class instance creation expression occurs in a static context, then i has no immediately enclosing instance.

– Otherwise, the immediately enclosing instance of i is this.

• If C is a local class, then:

– If C occurs in a static context, then i has no immediately enclosing instance.

– Otherwise, if the class instance creation expression occurs in a static context, then a compile-time error occurs.

– Otherwise, let O be the immediately enclosing class of C. Let n be an integer such that O is the n'th lexically enclosing type declaration of the class in which the class instance creation expression appears.

The immediately enclosing instance of i is the n'th lexically enclosing instance of this.

15.9 Class Instance Creation Expressions EXPRESSIONS

• If C is an inner member class, then:

– If the class instance creation expression is unqualified, then:

› If the class instance creation expression occurs in a static context, then a compile-time error occurs.

› Otherwise, if C is a member of a class enclosing the class in which the class instance creation expression appears, then let O be the immediately enclosing class of which C is a member. Let n be an integer such that O is the n'th lexically enclosing type declaration of the class in which the class instance creation expression appears.

The immediately enclosing instance of i is the n'th lexically enclosing instance of this.

› Otherwise, a compile-time error occurs.

– If the class instance creation expression is qualified, then the immediately enclosing instance of i is the object that is the value of the Primary expression or the ExpressionName.

If C is an anonymous class, and its direct superclass S is an inner class, then i may have an immediately enclosing instance with respect to S, determined as follows:

• If S is a local class, then:

– If S occurs in a static context, then i has no immediately enclosing instance with respect to S.

– Otherwise, if the class instance creation expression occurs in a static context, then a compile-time error occurs.

– Otherwise, let O be the immediately enclosing class of S. Let n be an integer such that O is the n'th lexically enclosing type declaration of the class in which the class instance creation expression appears.

The immediately enclosing instance of i with respect to S is the n'th lexically enclosing instance of this.

• If S is an inner member class, then:

– If the class instance creation expression is unqualified, then:

› If the class instance creation expression occurs in a static context, then a compile-time error occurs.

› Otherwise, if S is a member of a class enclosing the class in which the class instance creation expression appears, then let O be the immediately enclosing

EXPRESSIONS Class Instance Creation Expressions 15.9

class of which S is a member. Let n be an integer such that O is the n'th lexically enclosing type declaration of the class in which the class instance creation expression appears.

The immediately enclosing instance of i with respect to S is the n'th lexically enclosing instance of this.

› Otherwise, a compile-time error occurs.

– If the class instance creation expression is qualified, then the immediately enclosing instance of i with respect to S is the object that is the value of the Primary expression or the ExpressionName.

15.9.3 Choosing the Constructor and its Arguments

Let C be the class being instantiated. To create an instance of C, i, a constructor of

C is chosen at compile time by the following rules:

First, the actual arguments to the constructor invocation are determined:

• If C is an anonymous class with direct superclass S, then:

– If S is not an inner class, or if S is a local class that occurs in a static context, then the arguments to the constructor are the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the expression.

– Otherwise, the first argument to the constructor is the immediately enclosing instance of i with respect to S (§15.9.2), and the subsequent arguments to the constructor are the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the class instance creation expression.

• If C is a local class or a private inner member class, then the arguments to the constructor are the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the class instance creation expression.

• If C is a non-private inner member class, then the first argument to the constructor is the immediately enclosing instance of i (§8.8.1, §15.9.2), and the subsequent arguments to its constructor are the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the class instance creation expression.

15.9 Class Instance Creation Expressions EXPRESSIONS

• Otherwise, the arguments to the constructor are the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the expression.

Second, a constructor of C and corresponding return type and throws clause are determined:

• If the class instance creation expression uses <> to elide class type arguments, a list of methods m1...mn is defined for the purpose of overload resolution and type argument inference.

Let c1...cn be the constructors of class C. Let #m be an automatically generated name that is distinct from all constructor and method names in C. For all j (1 ≤ jn), mj is defined in terms of cj as follows:

– A substitution θj is first defined to instantiate the types in cj.

Let F1...Fp be the type parameters of C, and let G1...Gq be the type parameters (if any) of cj. Let X1...Xp and Y1...Yq be type variables with distinct names that are not in scope in the body of C.

θj is [F1:=X1, ..., Fp:=Xp, G1:=Y1, ..., Gq:=Yq]. – The modifiers of mj are those of cj.

– The type parameters of mj are X1...Xp,Y1...Yq. The bound of each parameter, if any, is θj applied to the corresponding parameter bound in C or cj.

– The return type of mj is θj applied to C<F1,...,Fp>. – The name of mj is #m.

– The (possibly empty) list of argument types of mj is θj applied to the argument types of cj.

– The (possibly empty) list of thrown types of mj is θj applied to the thrown types of cj.

– The body of mj is irrelevant.

To choose a constructor, we temporarily consider m1...mn to be members of C. Then one of m1...mn is selected, as determined by the class instance creation's argument expressions, using the process specified in §15.12.2.

If there is no unique most specific method that is both applicable and accessible, then a compile-time error occurs.

EXPRESSIONS Class Instance Creation Expressions 15.9

Otherwise, where mj is the selected method, cj is the chosen constructor. The return type and throws clause of cj are the same as the return type and throws

clause determined for mj (§15.12.2.6).

• Otherwise, the class instance creation expression does not use <> to elide class type arguments.

Let T be the type denoted by C followed by any class type arguments in the expression. The process specified in §15.12.2, modified to handle constructors, is used to select one of the constructors of T and determine its throws clause.

If there is no unique most-specific constructor that is both applicable and accessible, then a compile-time error occurs (as in method invocations).

Otherwise, the return type is T.

It is a compile-time error if an argument to a class instance creation expression is not compatible with its target type, as derived from the invocation type (§15.12.2.6).

If the compile-time declaration is applicable by variable arity invocation (§15.12.2.4), then where the last formal parameter type of the invocation type of the constructor is Fn[], it is a compile-time error if the type which is the erasure of

Fn is not accessible at the point of invocation.

The type of the class instance creation expression is the return type of the chosen constructor, as defined above.

Note that the type of the class instance creation expression may be an anonymous class type, in which case the constructor being invoked is an anonymous constructor (§15.9.5.1).

15.9.4 Run-Time Evaluation of Class Instance Creation Expressions At run time, evaluation of a class instance creation expression is as follows.

First, if the class instance creation expression is a qualified class instance creation expression, the qualifying primary expression is evaluated. If the qualifying expression evaluates to null, a NullPointerException is raised, and the class instance creation expression completes abruptly. If the qualifying expression completes abruptly, the class instance creation expression completes abruptly for the same reason.

Next, space is allocated for the new class instance. If there is insufficient space to allocate the object, evaluation of the class instance creation expression completes abruptly by throwing an OutOfMemoryError.

15.9 Class Instance Creation Expressions EXPRESSIONS

The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).

Next, the actual arguments to the constructor are evaluated, left-to-right. If any of the argument evaluations completes abruptly, any argument expressions to its right are not evaluated, and the class instance creation expression completes abruptly for the same reason.

Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type. This process can be directed by explicit constructor invocation statements (§8.8) and is specified in detail in §12.5.

The value of a class instance creation expression is a reference to the newly created object of the specified class. Every time the expression is evaluated, a fresh object is created.

Example 15.9.4-1. Evaluation Order and Out-Of-Memory Detection

If evaluation of a class instance creation expression finds there is insufficient memory to perform the creation operation, then an OutOfMemoryError is thrown. This check occurs before any argument expressions are evaluated.

So, for example, the test program:

class List { int value;

List next;

static List head = new List(0);

List(int n) { value = n; next = head; head = this; } }

class Test {

public static void main(String[] args) { int id = 0, oldid = 0;

try {

for (;;) { ++id;

new List(oldid = id);

}

} catch (Error e) { List.head = null;

System.out.println(e.getClass() + ", " + (oldid==id));

} } } prints:

EXPRESSIONS Class Instance Creation Expressions 15.9

class java.lang.OutOfMemoryError, false

because the out-of-memory condition is detected before the argument expression oldid

= id is evaluated.

Compare this to the treatment of array creation expressions, for which the out-of-memory condition is detected after evaluation of the dimension expressions (§15.10.2).

15.9.5 Anonymous Class Declarations

An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler.

An anonymous class is never abstract (§8.1.1.1).

An anonymous class is always implicitly final (§8.1.1.2).

An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1,

§8.5.1).

15.9.5.1 Anonymous Constructors

An anonymous class cannot have an explicitly declared constructor. Instead, an anonymous constructor is implicitly declared for an anonymous class. The form of the anonymous constructor for an anonymous class C with direct superclass S

is as follows:

• If S is not an inner class, or if S is a local class that occurs in a static context, then the anonymous constructor has one formal parameter for each actual argument to the class instance creation expression in which C is declared.

The actual arguments to the class instance creation expression are used to determine a constructor cs of S, using the same rules as for method invocations (§15.12). The type of each formal parameter of the anonymous constructor must be identical to the corresponding formal parameter of cs.

The constructor body consists of an explicit constructor invocation (§8.8.7.1) of the form super(...), where the actual arguments are the formal parameters of the constructor, in the order they were declared.

• Otherwise, the first formal parameter of the constructor of C represents the value of the immediately enclosing instance of i with respect to S (§15.9.2,

§15.9.3). The type of this parameter is the class type that immediately encloses the declaration of S.

Một phần của tài liệu Java SE 8 edition for everyone Java SE 8 edition for everyone Java SE 8 edtion for everyone (Trang 498 - 508)

Tải bản đầy đủ (PDF)

(780 trang)