Records and bi-directional relationships

Gunnar Morling gunnar at hibernate.org
Sat Dec 14 22:24:41 UTC 2019


Am Sa., 14. Dez. 2019 um 23:12 Uhr schrieb Brian Goetz <
brian.goetz at oracle.com>:

> I think you are asking: is it possible to create cycles with records?
>

Essentially, yes. I couldn't find anything on that topic in the JEP.


> And the answer is, mostly no.  (You can have records that have mutable
> components and then later mutate them to be cyclic.
>

That's interesting, how would I declare a mutable component? From reading
the JEP I concluded they'd be final.

In that light, isn't the potential SOE in toString() even more of a concern
than in the very specific corner case of an escaping reference I sketched?

What you're doing in the `Surface` constructor is allowing the `this`
> reference escape during construction, which undermines the memory model
> guarantees for final fields.


> On 12/14/2019 4:58 PM, Gunnar Morling wrote:
> > Hi all,
> >
> > I was exploring the records feature in the latest 14 EA build a bit. An
> > interesting question came up in how records will work for
> > bi-directional relationships between two record types.
> >
> > I found no way to instantiate such pair of records without creating a
> > temporary instance of one of the two (unlike with regular classes, where
> I
> > could wire the relationship from within the constructor of one). Did I
> miss
> > an alternative way to do so (see below for what I came up with)?
> >
> > A related question: this program will raise a StackOverflowError in the
> > toString() method. Is this an accepted limitation?
> >
> > Thanks,
> >
> > --Gunnar
> >
> >      public class RecordsBidi {
> >          public static void main (String... args) {
> >              Surface surface = new Surface(new Point(1, 2));
> >              System.out.println(surface);
> >          }
> >
> >          record Point(int x, int y, Surface owning) {
> >              public Point(int x, int y) {
> >                  this(x, y, null);
> >              }
> >          }
> >
> >          record Surface(Point center) {
> >              public Surface(Point center) {
> >                 this.center = new Point(center.x, center.y, this);
> >              }
> >          }
> >      }
>
>


More information about the amber-dev mailing list