<!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>