On Apr 27, 2022, at 5:01 PM, Dan Smith <daniel.sm...@oracle.com<mailto:daniel.sm...@oracle.com>> wrote:
Please see these two spec change documents for JLS and JVMS changes in support of the Value Objects feature. Here's a revision, including some additional language checks that I missed in the first iteration. http://cr.openjdk.java.net/~dlsmith/jep8277163/jep8277163-20220519/specs/value-objects-jls.html http://cr.openjdk.java.net/~dlsmith/jep8277163/jep8277163-20220519/specs/value-objects-jvms.html ---------- Diff of the changes: diff --git a/closed/src/java.se/share/specs/value-objects-jls.md<http://java.se/share/specs/value-objects-jls.md> b/closed/src/java.se/share/specs/value-objects-jls.md<http://java.se/share/specs/value-objects-jls.md> index 3e8e44aa2c..392242efb9 100644 --- a/closed/src/java.se/share/specs/value-objects-jls.md<http://java.se/share/specs/value-objects-jls.md> +++ b/closed/src/java.se/share/specs/value-objects-jls.md<http://java.se/share/specs/value-objects-jls.md> @@ -501,9 +501,9 @@ It is permitted for the class declaration to redundantly specify the `final` modifier. The `identity` and `value` modifiers limit the set of classes that can extend -an `abstract` class ([8.1.4]). +a non-`final` class ([8.1.4]). -Special restrictions apply to the field declarations ([8.3.1.2]), method +Special restrictions apply to the field declarations ([8.3.1]), method declarations ([8.4.3.6]), and constructors ([8.8.7]) of a class that is not an `identity` class. @@ -524,6 +524,61 @@ Should there be? +#### 8.1.3 Inner Classes and Enclosing Instances {#jls-8.1.3} + +... + +An inner class *C* is a *direct inner class of a class or interface O* if *O* is +the immediately enclosing class or interface declaration of *C* and the +declaration of *C* does not occur in a static context. + +> If an inner class is a local class or an anonymous class, it may be declared +> in a static context, and in that case is not considered an inner class of any +> enclosing class or interface. + +A class *C* is an *inner class of class or interface O* if it is either a direct +inner class of *O* or an inner class of an inner class of *O*. + +> It is unusual, but possible, for the immediately enclosing class or interface +> declaration of an inner class to be an interface. +> This only occurs if the class is a local or anonymous class declared in a +> `default` or `static` method body ([9.4]). + +A class or interface *O* is the *zeroth lexically enclosing class or interface +declaration of itself*. + +A class *O* is the *n'th lexically enclosing class declaration of a class C* if +it is the immediately enclosing class declaration of the *n-1*'th lexically +enclosing class declaration of *C*. + +An instance *i* of a direct inner class *C* of a class or interface *O* is +associated with an instance of *O*, known as the *immediately enclosing instance +of i*. +The immediately enclosing instance of an object, if any, is determined when the +object is created ([15.9.2]). + +An object *o* is the *zeroth lexically enclosing instance of itself*. + +An object *o* is the *n'th lexically enclosing instance of an instance i* if it +is the immediately enclosing instance of the *n-1*'th lexically enclosing +instance of *i*. + +An instance of an inner local class or an anonymous class whose declaration +occurs in a static context has no immediately enclosing instance. +Also, an instance of a `static` nested class ([8.1.1.4]) has no immediately +enclosing instance. + +**It is a compile-time error if an inner class has an immediately enclosing +instance but is declared an `abstract` `value` class ([8.1.1.1], [8.1.1.5]).** + +> **If an abstract class is declared with neither the `value` nor the `identity` +> modifier, but it is an inner class and has an immediately enclosing instance, +> it is implicitly an `identity` class, per [8.1.1.5].** + +... + + + #### 8.1.4 Superclasses and Subclasses {#jls-8.1.4} The optional `extends` clause in a normal class declaration specifies the @@ -761,8 +816,110 @@ instance method.** +### 8.6 Instance Initializers {#jls-8.6} + +An *instance initializer* declared in a class is executed when an instance of +the class is created ([12.5], [15.9], [8.8.7.1]). + +*InstanceInitializer:* +: *Block* + +**It is a compile-time error for an `abstract` `value` class to declare an +instance initializer.** + +> **If an abstract class is declared with neither the `value` nor the `identity` +> modifier, but it declares an instance initializer, it is implicitly an +> `identity` class, per [8.1.1.5].** + +It is a compile-time error if an instance initializer cannot complete normally +([14.22]). + +It is a compile-time error if a `return` statement ([14.17]) appears anywhere +within an instance initializer. + +An instance initializer is permitted to refer to the current object using the +keyword `this` ([15.8.3]) or the keyword `super` ([15.11.2], [15.12]), and to +use any type variables in scope. + +Restrictions on how an instance initializer may refer to instance variables, +even when the instance variables are in scope, are specified in [8.3.3]. + +Exception checking for an instance initializer is specified in [11.2.3]. + + + ### 8.8 Constructor Declarations {#jls-8.8} +A *constructor* is used in the creation of an object that is an instance of a +class ([12.5], [15.9]). + +*ConstructorDeclaration:* +: {*ConstructorModifier*} *ConstructorDeclarator* [*Throws*] *ConstructorBody* + +*ConstructorDeclarator:* +: [*TypeParameters*] *SimpleTypeName*\ + `(` [*ReceiverParameter* `,`] [*FormalParameterList*] `)` + +*SimpleTypeName:* +: *TypeIdentifier* + +The rules in this section apply to constructors in all class declarations, +including enum declarations and record declarations. +However, special rules apply to enum declarations with regard to constructor +modifiers, constructor bodies, and default constructors; these rules are stated +in [8.9.2]. +Special rules also apply to record declarations with regard to constructors, as +stated in [8.10.4]. + +The *SimpleTypeName* in the *ConstructorDeclarator* must be the simple name of +the class that contains the constructor declaration, or a compile-time error +occurs. + +In all other respects, a constructor declaration looks just like a method +declaration that has no result ([8.4.5]). + +Constructor declarations are not members. +They are never inherited and therefore are not subject to hiding or overriding. + +**It is a compile-time error for an `abstract` `value` class to declare a +nontrivial constructor ([8.1.1.5]).** + +> **If an abstract class is declared with neither the `value` nor the `identity` +> modifier, but it declares a nontrivial constructor, it is implicitly an +> `identity` class, per [8.1.1.5].** + +:::editorial +It's not ideal to define a new term just for the purpose of this rule. But the +list of things to check is long, and we don't want to repeat it. Perhaps it +would be helpful to somehow overlap this definition with the discussion of +default constructors in [8.8.9]. +::: + +Constructors are invoked by class instance creation expressions ([15.9]), by the +conversions and concatenations caused by the string concatenation operator `+` +([15.18.1]), and by explicit constructor invocations from other constructors +([8.8.7]). +Access to constructors is governed by access modifiers ([6.6]), so it is +possible to prevent class instantiation by declaring an inaccessible constructor +([8.8.10]). + +Constructors are never invoked by method invocation expressions ([15.12]). + +:::example + +Example 8.8-1. Constructor Declarations + +``` +class Point { + int x, y; + Point(int x, int y) { this.x = x; this.y = y; } +} +``` + +::: + + + #### 8.8.7 Constructor Body {#jls-8.8.7} The first statement of a constructor body may be an explicit invocation of @@ -2231,7 +2388,7 @@ synchronization. [8.1.1.4]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.1.1.4 [8.1.1.5]: #jls-8.1.1.5 [8.1.2]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.1.2 -[8.1.3]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.1.3 +[8.1.3]: #jls-8.1.3 [8.1.4]: #jls-8.1.4 [8.1.5]: #jls-8.1.5 [8.1.6]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.1.6 @@ -2260,9 +2417,9 @@ synchronization. [8.4.8.3]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.4.8.3 [8.4.9]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.4.9 [8.5]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.5 -[8.6]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.6 +[8.6]: #jls-8.6 [8.7]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.7 -[8.8]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.8 +[8.8]: #jls-8.8 [8.8.1]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.8.1 [8.8.2]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.8.2 [8.8.3]: https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.8.3 diff --git a/closed/src/java.se/share/specs/value-objects-jvms.md<http://java.se/share/specs/value-objects-jvms.md> b/closed/src/java.se/share/specs/value-objects-jvms.md<http://java.se/share/specs/value-objects-jvms.md> index fe747ad3bd..70e24541ce 100644 --- a/closed/src/java.se/share/specs/value-objects-jvms.md<http://java.se/share/specs/value-objects-jvms.md> +++ b/closed/src/java.se/share/specs/value-objects-jvms.md<http://java.se/share/specs/value-objects-jvms.md> @@ -1561,6 +1561,70 @@ Attribute Location `class` +#### 4.7.6 The `InnerClasses` Attribute {#jvms-4.7.6} + +... + +inner_class_access_flags + +: The value of the `inner_class_access_flags` item is a mask of flags used + to denote access permissions to and properties of class or interface *C* + as declared in the source code from which this `class` file was + compiled. + It is used by a compiler to recover the original information when source + code is not available. + The flags are specified in [Table 4.7.6-A]. + + ::: {.table #jvms-4.7.6-300-D.1-D.1} + + Table 4.7.6-A. Nested class access and property flags + + ---------------------------------------------------------------------------- + Flag Name Value Interpretation + ------------------------ ----------- --------------------------------------- + `ACC_PUBLIC` 0x0001 Marked or implicitly `public` in + source. + + `ACC_PRIVATE` 0x0002 Marked `private` in source. + + `ACC_PROTECTED` 0x0004 Marked `protected` in source. + + `ACC_STATIC` 0x0008 Marked or implicitly `static` in + source. + + `ACC_FINAL` 0x0010 Marked or implicitly `final` in + source. + + **`ACC_IDENTITY`** **0x0020** **Declared as an `identity` class or + interface.** + + **`ACC_VALUE`** **0x0040** **Declared as a `value` class or + interface.** + + `ACC_INTERFACE` 0x0200 Was an `interface` in source. + + `ACC_ABSTRACT` 0x0400 Marked or implicitly `abstract` in + source. + + `ACC_SYNTHETIC` 0x1000 Declared synthetic; not present in the + source code. + + `ACC_ANNOTATION` 0x2000 Declared as an annotation interface. + + `ACC_ENUM` 0x4000 Declared as an `enum` class. + ---------------------------------------------------------------------------- + + ::: + + All bits of the `inner_class_access_flags` item not assigned in [Table + 4.7.6-A] are reserved for future use. + They should be set to zero in generated `class` files and should be + ignored by Java Virtual Machine implementations. + +... + + + #### **4.7.31 The `Preload` Attribute** {#jvms-4.7.31} :::inserted