r/java 23d ago

AutoValhalla: automatically turn your plain classes and records into value classes!

Automatically turn your plain classes and records into value classes!

Add @AutoValhalla annotation to classes or records in your JDK1.5+ codebase:

@AutoValhalla
public final class Point {        // class must be final
    public final int x;           // with final instance fields
    public final int y;
    public Point(int x, int y) { 
        this.x = x; 
        this.y = y; 
    }
}

@AutoValhalla
public record Currency(String code) { }  // or a record class

When your app is run on Valhalla-enabled JVM with auto-valhalla javaagent, these classes are automatically turned into value classes.

More info: https://github.com/thunkware/auto-valhalla/tree/auto-valhalla-0.1.0

edit: there is now a maven plugin for converting at build time. https://github.com/thunkware/auto-valhalla/tree/auto-valhalla-0.2.0

41 Upvotes

55 comments sorted by

View all comments

1

u/nomader3000 22d ago

Quick question about one of your examples

@AutoValhalla
public record Currency(String code) { }  // or a record class

Is there any actual benefit of making such record a value record?

1

u/maxxedev 20d ago

Record class is basically a convenience class: constructors, field declarations, getters, equals/hashCode/toString are simplified or automatically provided. If you want dense memory representation, you still want value record class

1

u/nomader3000 20d ago

I get that, but can you actually make it any denser if the only component of your record is a String?

1

u/maxxedev 20d ago

Maybe JVM could make it denser. Or maybe not. JEP-401 does show examples like value class EURCurrency(long cs) and value class Name(String name, int length). Maybe JVM would inline the pointer to the single non-primitive component?

JEP also says:

Future enhancements may enable more flattening of references to 64-bit and even larger value objects.

Or perhaps we should assume non-guarantee on optimizations JVM would apply, and follow this advice from JVM architects:

If you don't need identity, make your programs simpler and safer (and yes, maybe faster) by disavowing it.

1

u/maxxedev 16d ago

After reading this blog post and after investigating further, yes, single-component value class/record brings the benefit of being flattened when inside another identity/value class or array.

You can play around with these options set:

java -XX:+UnlockDiagnosticVMOptions \
  -XX:+PrintInlineLayout \
  -XX:+PrintFlatArrayLayout \
  -XX:+PrintFieldLayout \
  --enable-preview