<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<br>
<br>
<blockquote type="cite" cite="mid:CAE+3fjZLdRjRgcKObsPmLTQvbv1mJJ1wkqS70+OBVf8R_J4GvA@mail.gmail.com">
<div dir="ltr">
<div>Well, as you have reposted this, I assume that you are not
against some discussion on the topic.</div>
<div><br>
</div>
<div>The both use-cases mentioned by Kai Hofmann are about
caching some intermediate computation derived from the record
fields to improve the performance of the application (they are
not strictly necessary for correctness). </div>
<div>In his case, such cached values are computed in the
constructor, which is somewhat unusual for (presumably heavy)
computation. What if we only use the methods that never access
these cached values? In this case, the computation will be
just a waste of CPU time.</div>
</div>
</blockquote>
<br>
The reason that is always cited for this feature request is "but
what about immutable state that is wholly derived from the
components" (basically, a cache.) And yes, this _is_ in the spirit
of "the state, the whole state, and nothing but the state"!
Unfortunately, the _proposed solution_ "let us declare off-label
final fields" is the same thing as "give us the ability to cache
data derived from the components." As an example:<br>
<br>
record Listy(int x) { <br>
private final List<String> impl = new
ArrayList<>();<br>
<br>
public void add(String s) { impl.add(s); }<br>
<br>
public boolean contains(String s) { return impl.contains(s);
}<br>
<br>
...<br>
}<br>
<br>
Is this a record wrapping one int, or a List implementation with
some free accessors and an incorrect implementation of
equals/hashCode? <br>
<br>
tl;dr: the _feature_ that he wants -- derived cached state -- is
reasonable. The _solution_ that is proposed -- is not that. A more
targeted feature would be required. <br>
<br>
Is making the field a LazyConstant sufficient to bring the
"solution" in line with the problem? Maybe. But really, this feels
more like a language feature for "cached method" or similar. We've
discussed this in the past but its pretty clear that given the scope
of such an exploration, it should not be at the top of the list.<br>
<br>
<blockquote type="cite" cite="mid:CAE+3fjZLdRjRgcKObsPmLTQvbv1mJJ1wkqS70+OBVf8R_J4GvA@mail.gmail.com">
<div dir="ltr">
<div>Usually, people perform heavy computations on demand,
deferring the computation until it's actually necessary (e.g.,
String.hash field). Now, we have a perfect construct for this:
LazyConstant. So I may imagine enhanced records with a new
feature:</div>
<div><br>
</div>
<div>- private final fields in records are allowed only if their
type is LazyConstant</div>
<div>- such fields must have an initializer like
LazyConstant.of(() -> lambda)</div>
<div>- the initializer is guaranteed to see the record
components. So we cannot use such fields in constructor prolog
(or in compact constructor), before all the components are
assigned</div>
<div>- it's assumed (though not statically checked) that such
fields depend on record components only. They are always
transient and not initialized after deserialization.</div>
<div><br>
</div>
<div>We may also devise some kind of syntactic sugar for
LazyConstant fields (not only in records!). E.g. declare them
like `private lazy T cached = initializer;` instead of
`private final LazyConstant<T> cached =
LazyConstant.of(() -> initializer);`. Having an ability to
declare such fields will simplify the record specification: we
can simply allow fields with 'lazy' modifier (which always
implies 'final') without saying anything about type.</div>
<div><br>
</div>
<div>I'm not saying that it's something that we should do right
now, especially taking into account that LazyConstants are
still in preview. But probably something useful here could be
done in the future.</div>
<div><br>
</div>
<div>With best regards,</div>
<div>Tagir Valeev</div>
</div>
<br>
<div class="gmail_quote gmail_quote_container">
<div dir="ltr" class="gmail_attr">On Thu, Dec 11, 2025 at
5:01 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div> <font size="4" face="monospace">The below was received
on amber-spec-comments. <br>
<br>
The author makes a renewed plea for final, non-component
fields in records. <br>
<br>
This point was discussed extensively during the design of
records, so I won't recapitulate the discussion here. </font>
<div><br>
<br>
-------- Forwarded Message --------
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">Subject:
</th>
<td>An improvement request on records</td>
</tr>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">Date:
</th>
<td>Thu, 11 Dec 2025 15:27:28 +0100</td>
</tr>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">From:
</th>
<td>Kai Hofmann <a href="mailto:java@kai-hofmann.de" target="_blank" moz-do-not-send="true"><java@kai-hofmann.de></a></td>
</tr>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">To:
</th>
<td><a href="mailto:amber-spec-comments@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amber-spec-comments@openjdk.org</a></td>
</tr>
</tbody>
</table>
<br>
<br>
To whom it may concern,<br>
<br>
I am working here since some years on my OpenSource
projects, and until now I had never a reason to made
comments on Java - but now I feel I have to raise my voice
on records:<br>
<br>
<br>
Since some years I developed a library of DDD valueObjects
both as normal Java objects and also in a parallel branch
as records. At the moment you can find this work here:<br>
<br>
<a href="https://urldefense.com/v3/__https://github.com/PowerStat/Validation__;!!ACWV5N9M2RV99hQ!JHAOFMJeOal-WSMN5Z0YieMexlUALgiI_eJrrVd1ExaK4sTWp1MrugbvoTi3Cpw7i4MMZH6IuLL5bzBt$" target="_blank" moz-do-not-send="true">https://github.com/PowerStat/Validation</a><br>
<br>
But I plan to rename this project, because in the meantime
the project name is no longer a good choice - maybe it
will name something like ValueObjectLibrary - you will
find it under my github repos.<br>
<br>
<br>
So from my experiences I can say it is a correct design
decision to not have instance fields within records.<br>
<br>
But in my opinion this thought is to simple, because
private "final" instance fields should be possible and
will be useful and could safe duplicated code as well as
runtime!<br>
<br>
So the point is that final instance fields have to be
initialized within the constructor and will be
unchangeable after a record has been constructed - so they
are harmless!<br>
<br>
As an example I have implemented a MACAddress class/record
that represents a hardware mac address.<br>
<br>
Within the normal class implementation I split the mac
address into it's parts only once within the construtor,
later on I have multiple methods that work on this split
parts.<br>
<br>
But within a record this is not possible so I have to do
the split within every method where I need it - thats
waste of code and runtime!<br>
<br>
Another example is my implementation of the ISBN13 - see <a href="https://urldefense.com/v3/__https://en.wikipedia.org/wiki/ISBN__;!!ACWV5N9M2RV99hQ!JHAOFMJeOal-WSMN5Z0YieMexlUALgiI_eJrrVd1ExaK4sTWp1MrugbvoTi3Cpw7i4MMZH6IuIV6HuOp$" target="_blank" moz-do-not-send="true">https://en.wikipedia.org/wiki/ISBN</a><br>
<br>
These numbers could come with 2 different formats: with or
without separator chars in it - both formats are equal.<br>
<br>
So in my class implementation I would do a normalization
(without separators) and store this one internally.<br>
<br>
Within a record this normalization in the construtor is
not possible, because I could not have instance fields nor
could I change the records parameter within the
constructor because its already fixed :(<br>
<br>
So ISBN13 could not be implemented as a record!<br>
<br>
I vote for extending the record specification to have
private "final" instances within it and maybe to allow to
manipulate the construction parameters within the
constructor.<br>
<br>
Would be nice to hear from you about this.<br>
<br>
<br>
Greetings and have a nice Christmas and a Happy New Year.<br>
<br>
<br>
PowerStat (Kai Hofmann)<br>
<br>
<br>
</div>
</div>
</blockquote>
</div>
</blockquote>
<br>
</body>
</html>