Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8323432

2.9: Revise special method description

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • 25
    • 21
    • specification
    • vm

      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.

            dlsmith Dan Smith
            dlsmith Dan Smith
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: