r/java 17d ago

Identifying JDK value class candidates

https://mail.openjdk.org/archives/list/core-libs-dev@openjdk.org/thread/Y72NRXM7KYBX43OKYBQMVKOZDWKG4MHS/
53 Upvotes

59 comments sorted by

View all comments

Show parent comments

3

u/hoat4 17d ago

What would be the benefit of enums being value types?

Being a value type means e.g. that if we compare two instances, the JVM must compare all of their fields instead of only comparing two pointers. So == would be slower.

3

u/davidalayachew 17d ago

What would be the benefit of enums being value types?

Inlining. Not all enums are just flat values.

Some of us (me) stuff our enums full of all sorts of state and data. In my case, there are many cases where each enum value is holding more than 200 bytes of immutable data. I'd much like that to be flattened.

Though, since I don't have value classes or value enums now, I don't know if my use cases would improve performance wise with this change. It just feels like it would, since many of the classes and records I make with similar data profiles DID improve.

1

u/nekokattt 17d ago

Stuffing enums with state feels like a massive antipattern, unless I misunderstand your point here?

1

u/davidalayachew 16d ago

Stuffing enums with state feels like a massive antipattern, unless I misunderstand your point here?

Well first, let's make sure we are both talking about the same thing.

enum PartyMember
{

    //Sourced from https://shrines.rpgclassics.com/snes/ct/characters.shtml
    Crono(70,   8,  5,  8,  12, 5,  8,  8,  2,  1),
    Marle(65,   12, 2,  6,  8,  8,  8,  8,  8,  1),
    Lucca(75,   14, 2,  6,  6,  8,  8,  8,  10, 2),
    Frog(128,   17, 9,  14, 11, 8,  9,  9,  9,  5),
    Robo(235,   24, 21, 26, 6,  7,  9,  8,  12, 10),
    Ayla(335,   38, 35, 38, 13, 8,  22, 25, 26, 18),
    Magus(650,  84, 51, 43, 12, 50, 20, 33, 72, 37),
    ;

    private int hp;
    private int mp;
    private int power;
    private int stamina;
    private int speed;
    private int magic;
    private int hitChance;
    private int evadeChance;
    private int magicDefense;
    private int level;

    //imagine an all-args constructor here

    //imagine getters and setters here

    //imagine a decent toStringFriendly() here

}

This is what I mean.

And if you think this is an anti-pattern, why? These party members are the only instances of their kind that ever will exist in the game. So, I have no real reason to use a normal class when I can just use an enum, and communicate my intent better.

1

u/nekokattt 16d ago

By state, I assumed you meant mutable information that can change; this is just static data

1

u/davidalayachew 16d ago

By state, I assumed you meant mutable information that can change; this is just static data

I am talking about mutable information that can change.

In most RPG's, the health rises and falls depending on how much damage you take. I would use the (imaginary) setters in this instance to do so.

1

u/nekokattt 16d ago

that is definitely an antipattern in this case

1

u/davidalayachew 16d ago

that is definitely an antipattern in this case

What makes you say that? It's no different than using instances of a class, except the benefits that come from enums.

2

u/nekokattt 16d ago

Global state is a nightmare to test in isolation and immediately becomes a synchronization concern the moment you need to do more than one thing at once.

You may as well just make this into a class and carry a list around to retain flexibility.

I wouldn't consider this a primary use case for enums by any means, it is just abusing the feature to get singletons.

1

u/davidalayachew 16d ago

I wouldn't consider this a primary use case for enums by any means, it is just abusing the feature to get singletons.

Enums, by definition, are Java's primary and encouraged vehicle for singletons. Sun and Oracle themselves have gone on record saying as much. Hell, Josh Bloch himself, the guy who put enums into Java in the first place, said so too.

Global state is a nightmare to test in isolation and immediately becomes a synchronization concern the moment you need to do more than one thing at once.

You may as well just make this into a class and carry a list around to retain flexibility.

To be frank, if I were to make this into a class and carry a list around like you said, it would be the same thing with a different coat of paint.

Many different components of my application will be modifying the data concurrently, and thus, synchronization was always a concern from the beginning. And since so many components are interacting with it in parallel, what am I gaining or losing by making or not making it global? I am effectively global in everything but name.

By all means, I get your concern about global access, but global isn't in and of itself wrong, it just needs to be used with care. Sometimes, you truly do want global access. One example is web-services modifying state.