-
Bug
-
Resolution: Unresolved
-
P4
-
21
The description of *special methods* confusingly suggests that some methods may be named <init> or <clinit>, but not be special methods. This leads to, or suggests the need for, unnecessary qualifications later in JVMS (like "if the method is named '<init>' and is an instance initialization method").
In older JVMs, this was a notable corner case; but since JDK 9 and JVMS 9, methods named `<init>` that, e.g., are declared in interfaces or with a non-`void` return cause a `ClassFormatError`. It's confusing to present these malformed declarations as anything other than errors.
A simpler scheme is to key everything off of the name: '<init>' defines an instance initialization method; '<clinit>' defines a class initialization method. Various constraints are enforced for methods with these names.
Proposed revisions to sections 2.9.1 and 2.9.2:
#### 2.9.1 Instance Initialization Methods {#jvms-2.9.1}
A class has zero or more *instance initialization methods*, **used to initialize
instances of the class.**
~~each~~ **Each** typically ~~corresponding~~ **corresponds** to a constructor
written in the Java programming language.
**If a class does not have an instance initialization method, its instances
cannot be initialized or used.**
~~A method is an instance initialization method if all of the following are true:~~
- ~~It is defined in a class (not an interface).~~
- ~~It has the special name `<init>`.~~
- ~~It is `void` ([4.3.3]).~~
~~In a class, any non-`void` method named `<init>` is not an instance
initialization method.
In an interface, any method named `<init>` is not an instance initialization
method.
Such methods cannot be invoked by any Java Virtual Machine instruction ([4.4.2],
[4.9.2]) and are rejected by format checking ([4.6], [4.8]).~~
**An instance initialization method is declared with the special name
`<init>`.**
**An instance initialization method may not be declared in an interface
([4.6]).**
The declaration and use of an instance initialization method is constrained by
the Java Virtual Machine.
For the declaration, the method's `access_flags` item**, descriptor,** and
`code` array are constrained ([4.6], [4.9.2]).
For a use, an instance initialization method may be invoked only by the
*invokespecial* instruction on an uninitialized class instance (~~[4.10.1.9]~~
**[4.9.1], [4.9.2]**).
> Because the name `<init>` is not a valid identifier in the Java programming
> language, it cannot be used directly in a program written in the Java
> programming language.
#### 2.9.2 Class Initialization Methods {#jvms-2.9.2}
A class or interface has at most one *class or interface initialization method*
and is initialized by the Java Virtual Machine invoking that method ([5.5]).
**If a class or interface does not have a class or interface initialization
method, initialization of the class or interface proceeds without executing
any bytecode in the class or interface.**
~~A method is a *class or interface initialization method* if all of the following
are true:~~
- ~~It has the special name `<clinit>`.~~
- ~~It is `void` ([4.3.3]).~~
- ~~In a `class` file whose version number is 51.0 or above, the method has its
`ACC_STATIC` flag set and takes no arguments ([4.6]).~~
> ~~The requirement for `ACC_STATIC` was introduced in Java SE 7, and for
> taking no arguments in Java SE 9.
> In a class file whose version number is 50.0 or below, a method named
> `<clinit>` that is `void` is considered the class or interface
> initialization method regardless of the setting of its `ACC_STATIC` flag
> or whether it takes arguments.~~
~~Other methods named `<clinit>` in a `class` file are not class or interface
initialization methods.
They are never invoked by the Java Virtual Machine itself, cannot be invoked by
any Java Virtual Machine instruction ([4.9.1]), and are rejected by format
checking ([4.6], [4.8]).~~
**A class or interface initialization method is declared with the special name
`<clinit>`.**
**At the declaration of a class or interface initialization method, the
`access_flags` item and descriptor are constrained by the Java Virtual
Machine ([4.6]).**
**It is impossible to directly reference or invoke a class or interface
initialization method ([4.4.2]).**
> Because the name `<clinit>` is not a valid identifier in the Java programming
> language, it cannot be used directly in a program written in the Java
> programming language.
In older JVMs, this was a notable corner case; but since JDK 9 and JVMS 9, methods named `<init>` that, e.g., are declared in interfaces or with a non-`void` return cause a `ClassFormatError`. It's confusing to present these malformed declarations as anything other than errors.
A simpler scheme is to key everything off of the name: '<init>' defines an instance initialization method; '<clinit>' defines a class initialization method. Various constraints are enforced for methods with these names.
Proposed revisions to sections 2.9.1 and 2.9.2:
#### 2.9.1 Instance Initialization Methods {#jvms-2.9.1}
A class has zero or more *instance initialization methods*, **used to initialize
instances of the class.**
~~each~~ **Each** typically ~~corresponding~~ **corresponds** to a constructor
written in the Java programming language.
**If a class does not have an instance initialization method, its instances
cannot be initialized or used.**
~~A method is an instance initialization method if all of the following are true:~~
- ~~It is defined in a class (not an interface).~~
- ~~It has the special name `<init>`.~~
- ~~It is `void` ([4.3.3]).~~
~~In a class, any non-`void` method named `<init>` is not an instance
initialization method.
In an interface, any method named `<init>` is not an instance initialization
method.
Such methods cannot be invoked by any Java Virtual Machine instruction ([4.4.2],
[4.9.2]) and are rejected by format checking ([4.6], [4.8]).~~
**An instance initialization method is declared with the special name
`<init>`.**
**An instance initialization method may not be declared in an interface
([4.6]).**
The declaration and use of an instance initialization method is constrained by
the Java Virtual Machine.
For the declaration, the method's `access_flags` item**, descriptor,** and
`code` array are constrained ([4.6], [4.9.2]).
For a use, an instance initialization method may be invoked only by the
*invokespecial* instruction on an uninitialized class instance (~~[4.10.1.9]~~
**[4.9.1], [4.9.2]**).
> Because the name `<init>` is not a valid identifier in the Java programming
> language, it cannot be used directly in a program written in the Java
> programming language.
#### 2.9.2 Class Initialization Methods {#jvms-2.9.2}
A class or interface has at most one *class or interface initialization method*
and is initialized by the Java Virtual Machine invoking that method ([5.5]).
**If a class or interface does not have a class or interface initialization
method, initialization of the class or interface proceeds without executing
any bytecode in the class or interface.**
~~A method is a *class or interface initialization method* if all of the following
are true:~~
- ~~It has the special name `<clinit>`.~~
- ~~It is `void` ([4.3.3]).~~
- ~~In a `class` file whose version number is 51.0 or above, the method has its
`ACC_STATIC` flag set and takes no arguments ([4.6]).~~
> ~~The requirement for `ACC_STATIC` was introduced in Java SE 7, and for
> taking no arguments in Java SE 9.
> In a class file whose version number is 50.0 or below, a method named
> `<clinit>` that is `void` is considered the class or interface
> initialization method regardless of the setting of its `ACC_STATIC` flag
> or whether it takes arguments.~~
~~Other methods named `<clinit>` in a `class` file are not class or interface
initialization methods.
They are never invoked by the Java Virtual Machine itself, cannot be invoked by
any Java Virtual Machine instruction ([4.9.1]), and are rejected by format
checking ([4.6], [4.8]).~~
**A class or interface initialization method is declared with the special name
`<clinit>`.**
**At the declaration of a class or interface initialization method, the
`access_flags` item and descriptor are constrained by the Java Virtual
Machine ([4.6]).**
**It is impossible to directly reference or invoke a class or interface
initialization method ([4.4.2]).**
> Because the name `<clinit>` is not a valid identifier in the Java programming
> language, it cannot be used directly in a program written in the Java
> programming language.
- relates to
-
JDK-8323437 Reject pre-51.0 classes with <clinit> methods with arguments
-
- Open
-
-
JDK-8130682 2.9: Clarify class and interface initialization methods
-
- Closed
-