From alex.buckley at oracle.com Wed Apr 4 22:21:39 2018 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 04 Apr 2018 15:21:39 -0700 Subject: Mistake in JLS 8.4.1 (Java SE 8 / 9 /10) In-Reply-To: <1b781713-c25f-97e4-f163-20044d73243d@ripstech.com> References: <1b781713-c25f-97e4-f163-20044d73243d@ripstech.com> Message-ID: <5AC54FF3.6040504@oracle.com> You make a fair point. We'll clarify this statement (or maybe even drop it) as part of reworking 8.4.1 for JEP 323 (var in lambda formals). Alex On 3/29/2018 7:15 AM, Malte Skoruppa wrote: > Dear JLS Team, > > I found what I believe to be a small mistake in section 8.4.1 of the JLS > for Java SE 8, 9, and 10. > > In this section it is stated: > >> If a method or constructor has no formal parameters, only an empty >> pair of parentheses appears in the declaration of the method or >> constructor. >> > I believe this statement to be incorrect for the following reason: > > If a method or constructor that has no formal parameters uses a receiver > parameter in its declaration, then no empty pair of parentheses appears > in the declaration, even though the method or constructor has no formal > parameters. This directly contradicts the above statement. > > For example, the method: > > class A { > > foo(A this) { ... } > > } > > has no formal parameters, yet no empty pair of parentheses appears in > its declaration. > > I can tell from personal experience that the statement is indeed > confusing: When I read it at first, I implicitly inferred from it that a > receiver parameter must also be (a special kind of) formal parameter > (since otherwise the statement would be incorrect). However, this is not > true. Later in the same section (8.4.1), it is explicitly stated that: > >> The receiver parameter is not a formal parameter > > Therefore I propose to rephrase the statement as follows: > >> If a method or constructor has no formal parameters *and does not >> specify a receiver parameter*, only an empty pair of parentheses >> appears in the declaration of the method or constructor. >> > ...or similar. > > Best, > From alex.buckley at oracle.com Wed Apr 4 22:27:51 2018 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 04 Apr 2018 15:27:51 -0700 Subject: Probably missing "or are effectively final" in Example 8.1.3-2. In-Reply-To: <124487173-a164868605860b7392557476c4bf309c@pmq2v.m5r2.onet> References: <124487173-a164868605860b7392557476c4bf309c@pmq2v.m5r2.onet> Message-ID: <5AC55167.4030705@oracle.com> Thanks, good catch and suggestion. Alex On 12/9/2016 2:00 PM, Jan Kurnatowski wrote: > Hello, > in https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3 in "Example 8.1.3-2. Inner Class Declarations": > "class Outer { > int i = 100; > static void classMethod() { > final int l = 200; > class LocalInStaticContext { > int k = i; // Compile-time error > int m = l; // OK > } > } > void foo() { > class Local { // A local class > int j = i; > } > } > } > The declaration of class LocalInStaticContext occurs in a static context due to being within the static method classMethod. Instance variables of class Outer are not available within the body of a static method. In particular, instance variables of Outer are not available inside the body of LocalInStaticContext. However, local variables from the surrounding method may be referred to without error (provided they are marked final)." > the last sentence should probably also include information about local variables that are effectively final, for example: > "However, local variables from the surrounding method may be referred to without error (provided they are declared final or are effectively final)." > I conclude this from the following sentence in https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3 : > "Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (?4.12.4), or a compile-time error occurs where the use is attempted." > For testing purposes I also changed the line "final int l = 200;" to "int l = 200;" and removed the line "int k = i; // Compile-time error" in the aforementioned code, and compiled it with Oracle Java 1.8.0_111 compiler - there was no compile-time error in the line "int m = l; // OK" after this modification. > Regards, > Jan Kurnatowski >