Queries regarding value classes

Julian Waters tanksherman27 at gmail.com
Tue Mar 15 03:12:23 UTC 2022


So if I understand correctly, value objects are essentially the same as
JEP-401's primitives but with nullability, and according to JEP-401,
guarantee of atomic modification?

"you are saying "change the a field of the object referred to by x to 3.""

Regarding this earlier x.a = 3 example, if X was a good ol' identity
object, x would then be a reference to the actual instance, and we'd simply
follow the reference to where the actual object is stored and set a to 3.
But if it was a value object, my understanding from your previous post is
that it would be stored directly on the abstract (Ignoring HotSpot's actual
complex implementation) stack to be operated on as a bunch of fields with
no additional metadata other than the check for null. What's stopping us
from then changing those fields directly? Like Quân Anh mentioned earlier,
we would've effectively created a new object if we did do that, since a
value object has no identity, but wouldn't we have technically changed the
value of a after initialization? At the very least, I'd say it would be
useful syntactic sugar to be able to do x.a on a value object instead of
having to do new X(3); every time we wanted to change it, unless a is
explicitly marked as final, without affecting == or related checks in any
way, since (from what I know) value objects are compared by field with ==.

Apologies for my lack of knowledge in this area, it still feels like I
haven't really gotten a correct idea of what value types really are,
especially compared to the true primitives of 401

Thanks for the reply and have a great day!

best regards,
Julian

On Tue, Mar 15, 2022 at 5:59 AM Brian Goetz <brian.goetz at oracle.com> wrote:

> You are (understandably) conflating the properties of identity with the
> properties of reference-ness.
>
> If you say
>
>     x.a = 3
>
> you are saying "change the a field of the object referred to by x to 3."
> The key to this sentence is *the object*; in order for assignment to make
> sense, you have to know exactly which variable you are talking about.  And
> if that variable is an instance field, then you have to know exactly which
> object it lives in.  This is where identity comes in; if x is a reference
> to an identity object, we then know how to find it.  Which means, you need
> an identity in order to be able to talk about mutability in a well-defined
> way.
>
> So if that's true, what is a *reference* to a value?  This is the
> confusing part.  If you think in terms of implementation, you'll probably
> think "reference means pointer", which puts you into a C frame of mind,
> because pointers always point at things.  But that's not what reference
> means in Java; its a more abstract kind of indirection.
>
> The distinction between int and Integer may be helpful.  At one level, int
> and Integer may seem like "almost the same sets of values"; the Integer
> value set has one more value -- null -- than the int value set, and for
> each of the other values, there is a bidirectional, 1:1 mapping between the
> two value sets.  But if we look closer, in fact these value sets are
> disjoint!  An int is not an Integer (even if they describe the same
> number.)
>
> So one big difference between references and values is nullability; null
> is a special kind of reference, the reference to no object at all.
> Reference types can be null; primitive types cannot.  (There's another,
> even more subtle distinction, which is tearability, which comes from the
> guarantees of the Java memory model.)
>
> If we have a value class:
>
>     value class X { }
>
> this gives rise to a reference type X, whose values are references to
> instances of X.  But those instances do not have identity, which means we
> can freely shred an X into the values of its fields, and later reconstitute
> it into a new X, all without anyone noticing.  That's what the lack of
> identity enables.  But the flip side of that means that any given X does
> not "live" anywhere; it is just a loose aggregation field values, which
> behaves like an object when called upon to do object-y things.
>
>
>
>
>
> On 3/13/2022 5:46 AM, Julian Waters wrote:
>
> Hi Quân Anh, thanks for the reply,
>
> I think I understand what you mean; Since value objects have no identity,
> changing their fields would essentially mean the object is now entirely
> different. However since that's the case, I'm still a little confused by
> the semantics of what they really are. Specifically, most of their benefits
> are centered around them being nothing more than their fields in memory,
> but at the same time documentation states that they're referred to by
> reference, which I find a little contradictory. If it's the former, they'd
> be no different from primitives, and if the latter, they'd be the exact
> same as identity objects, which has left me puzzled for quite some time.
>
> Sorry for all the trouble, have a great day
>
> best regards,
> Julian
>
> On Sun, Mar 13, 2022 at 4:26 PM Quân Anh Mai <anhmdq at gmail.com> <anhmdq at gmail.com> wrote:
>
>
> Hi,
>
> Regarding your concern of mutable value objects, having a mutable
> identity-less object is illogical. Because a value class does not have a
> unique identity, upon modification, the object is changed to become another
> object. A value object is immutable in the same way that an int is
> immutable. You can change a variable int a from containing a value of 3
> to a value of 4, but you can’t change the number itself, it has been
> mathematically and programmatically defined to be a specific bit sequence.
> Similarly, you can change a variable Point a from enclosing the point (3,
> 4) into the point (2, 5), but you can’t change the coordination of the
> points themselves, they have been (in this case) also mathematically
> defined. Your understanding of how value classes work is also not correct.
> The fact that a value object can be deconstructed to its fields does not
> mean that it will. This is simply an optimisation choice of the compiler.
>
> Regards,
> Quan Anh
>
> On Sun, 13 Mar 2022 at 15:42, Julian Waters <tanksherman27 at gmail.com> <tanksherman27 at gmail.com>
> wrote:
>
>
> Hi all,
>
> I'd like to discuss several topics related to the current draft on value
> classes.
>
> As mentioned in another post to this list at
> https://mail.openjdk.java.net/pipermail/valhalla-dev/2022-January/009871.html
> ,
> currently value classes are specified as immutable, with all fields being
> declared as final. If I understand this correctly, value based classes,
> unlike the true primitives which work is currently focused on, can still
> be
> referred to by references; It is only identity that has been given up. In
> that instance, naively speaking, wouldn't it be possible for value objects
> to have mutable fields? In the same way that one can reference the fields,
> one might possibly be able to also change their values through the
> available object reference as well. From what I can tell, value objects
> are
> planned to work internally by decomposing them to nothing more than their
> constituent fields and reconstructing them elsewhere. If that is the case,
> shouldn't modification of their fields be possible? To me it seems the
> modification would simply modify the copied value object *b *while leaving
> original value object *a *unchanged, which sits perfectly with the
> constraint that identity should not be supported. Am I mistaken in my
> assumption?
>
> Additionally, if the above holds true, I also suggest allowing an object
> to
> be declared as value based at the site of their usage, instead of just at
> their definition. Something like
>
> // Item is by default an identity class, but the field "item" here is now
> // a value object due to the declaration of value
> value Item item = new Item();
>
> would allow typical identity classes to be treated as value objects where
> they're used. This would, to me, present a great deal of flexibility as
> one
> could then choose how to allocate a particular object without
> constraining *every
> *instance of that class to a specific value/identity dichotomy, and also
> avoids the hassle of having to know which classes should be value or
> identity types ahead of time. On a side note, the current proposal also
> includes the ability to mark records as value based, given that records
> are
> meant exclusively as data classes, I suggest we flip that around and
> instead have records as *value based by default, *and instead allow
> marking
> them as identity objects explicitly if required, with the currently used
> ref keyword (Or whatever ref will eventually become), both at definition
> and when an actual instance is constructed, as mentioned above. This could
> save frustration from having to type value over and over whenever writing
> the definition of a new record.
>
> Have a great day, hope I can hear your opinions on this! :)
>
> best regards,
> Julian
>
>
>
>



More information about the valhalla-dev mailing list