[records] Compile-time constants can be used in local classes static members but cannot be used in records

Mateusz Romanowski romanowski.mateusz at gmail.com
Wed Jan 29 17:46:33 UTC 2020


Hi Alex et al.,

How would we understand an up-level `final Object lock = new Object();`
then?

Should we perhaps resurrect C-like `static final` variables inside methods
to allow static nested non-constexpr variables?

/Mateusz


W dniu środa, 29 stycznia 2020 Alex Buckley <alex.buckley at oracle.com>
napisał(a):
> Note that the up-level variable in this case -- `final int x = 2;` -- is
a constant variable, but not a static constant variable (or a static member
of anything). Still, the simple name `x` is in scope in the body of nested
{class, record} X, and counts as a constant expression, so RecordTest
should compile in 15 once when JDK-8236189 is undone/relaxed.
>
> Alex
>
> On 1/29/2020 6:44 AM, Brian Goetz wrote:
>>
>> Tagir is right, and this is yet another aspect of our technical debt
with regard to nesting.  Nested entities of all stripes (static vs
instance, class vs interface vs record vs enum) can access static members
from lexically enclosing contexts.
>>
>>
>>
>> On 1/29/2020 2:03 AM, Tagir Valeev wrote:
>>>
>>> But:
>>>
>>> 1. Compile time constant is not the state.
>>> 2. Static field of local class also cannot capture any state, even
>>> technically (because there's no place to store the state). Yet, this
code
>>> is allowed. I observe asymmetry here.
>>>
>>> With best regards,
>>> Tagir Valeev.
>>>
>>> ср, 29 янв. 2020 г., 10:39 Vicente Romero <vicente.romero at oracle.com>:
>>>
>>>> Hi Tagir,
>>>>
>>>> This behavior is in accordance with the spec: a local record is not a
>>>> local class, local records are not allowed to capture any state from
its
>>>> enclosing type. We plan to revisit this in the future not only for
>>>> record but as a general effort on nested-ness but for the time being we
>>>> preferred to let local records immune to any capture rule that applies
>>>> to local classes
>>>>
>>>> Vicente
>>>>
>>>> On 1/28/20 10:01 PM, Tagir Valeev wrote:
>>>>>
>>>>> Hello!
>>>>>
>>>>> This code is perfectly compilable (javac 14-ea+33-1439):
>>>>>
>>>>> public class RecordTest {
>>>>>       public static void main(String[] args) {
>>>>>           final int x = 2;
>>>>>           class X {
>>>>>               static final int y = x;
>>>>>           }
>>>>>       }
>>>>> }
>>>>>
>>>>> This is not (simply changed class to record, leaving everything else
the
>>>>
>>>> same):
>>>>>
>>>>> public class RecordTest {
>>>>>       public static void main(String[] args) {
>>>>>           final int x = 2;
>>>>>           record X() {
>>>>>               static final int y = x;
>>>>>           }
>>>>>       }
>>>>> }
>>>>>
>>>>> Error:(5, 34) java: non-static variable x cannot be referenced from a
>>>>> static context
>>>>>
>>>>> This looks counter-intuitive to me: why static field in one case can
>>>>> refer to compile-time constant and in another case cannot?
>>>>>
>>>>> With best regards,
>>>>> Tagir Valeev
>>>>
>>
>


More information about the amber-dev mailing list