amber: the language keeps moving
derived record creation, and what happened to string templates.
- chapter
- chapter 18.03
- reading time
- 7 min read
- preview
Project Amber ships java's language features in small pieces, through previews. as of october 2026, three things are in flight: derived record creation (p with { x = 0; }, a JEP candidate that isn't targeted to any release), primitive types in patterns (a fifth preview in jdk 27), and carrier classes (a design note about what comes after records).
and one came back out: string templates were previewed in 21 and 22, then withdrawn in 2024. preview really does mean preview.
the picture
you know how records, pattern matching for switch, text blocks and var all showed up over a few years, each one small? that's Amber's style: right-sized language features, each one previewed, adjusted, and only then made permanent (the whole run so far is in the release timeline, and what's in preview right now is in in preview).
think of a restaurant testing new dishes as specials. most become regulars after a few tweaks. some get reworked several times. and once in a while one gets pulled from the menu entirely, because the kitchen figured out a better way to make it. string templates were that dish.
derived record creation
records are immutable, so "this record, but with x changed" means calling the constructor with every component, by hand:
Point next = new Point(0, loc.y(), loc.z()); // today: repeat every other componentwith ten components that's a typo waiting to happen, and adding an eleventh breaks every one of these calls. so people write withX(...) methods, one per component. JEP 468 proposes the language do it:
// JEP 468 (derived record creation): a candidate, not in any jdk. illustrative only.
Point next = loc with { x = 0; };
Point bigger = next with {
x *= 2;
y *= 2;
z *= 2;
};the block isn't magic syntax. it's ordinary code running on local variables named after the components:
the whole thing is one expression: start from an existing record, list only what changes. loc is Point[x=3, y=4, z=5].
as of october 2026 it's still a candidate: created in late 2023, last updated in april 2024, not targeted to any release, and the JEP doesn't say why. the likely answer is in Amber's newest design note (below): reconstruction is one piece of a bigger design about data classes that aren't records, and it makes sense to design them together. on jdk 25 the syntax doesn't even parse (error: not a statement).
string templates, withdrawn
void main() {
String name = "ada";
IO.println(STR."Hello \{name}");
}the design had a template processor in front of every template (STR., FMT., or your own, say, for safe SQL). people found that processor-first design confusing, and it didn't compose well, which is the reasoning in the JDK issue that removed it (JDK-8329949). there was broad agreement it needed to change and no agreement yet on how, so the team pulled it rather than freeze a design they weren't happy with. as of october 2026 there's no new string template JEP.
meanwhile, the boring answers are fine:
void main() {
String name = "ada";
int count = 3;
IO.println("hello " + name + ", you have " + count + " messages"); // compiled to invokedynamic
IO.println("hello %s, you have %d messages".formatted(name, count));
}hello ada, you have 3 messages hello ada, you have 3 messages
+ on strings has been compiled to an efficient invokedynamic call since java 9 (see string concatenation internals), and formatted covers the rest. for SQL, the right tool was never interpolation anyway: it's a PreparedStatement with ? parameters.
primitive types in patterns
the one that's closest to done. it lets instanceof and switch work with every primitive type, and "matches" means the conversion is exact: nothing lost. the details and more examples are in in preview. here's the exactness rule on its own:
instanceof float is false. the same table, run for real on jdk 25 with --enable-preview, is below.// jdk 25 with --enable-preview (JEP 507, the third preview). jdk 27 previews it again (JEP 532).
void main() {
for (int v : new int[] {42, -129, 1000, 65535, 16777217, 2147483647}) {
IO.println(v + ": byte " + (v instanceof byte) + ", short " + (v instanceof short) + ", char " + (v instanceof char)
+ ", float " + (v instanceof float) + ", long " + (v instanceof long) + ", double " + (v instanceof double));
}
}42: byte true, short true, char true, float true, long true, double true -129: byte false, short true, char false, float true, long true, double true 1000: byte false, short true, char true, float true, long true, double true 65535: byte false, short false, char true, float true, long true, double true 16777217: byte false, short false, char false, float false, long true, double true 2147483647: byte false, short false, char false, float false, long true, double true
five previews (23 through 27) is a lot for a feature this size, and it shows how careful the team is with anything that touches conversions: jdk 26 changed the exact definition of "unconditionally exact" and tightened which cases count as dominated. as of october 2026 it isn't on the jdk 28 list.
what's next: data beyond records
Amber's newest design note, "Data-Oriented Programming for Java: Beyond Records" (january 2026), calls records, sealed types and record patterns the first arc of data-oriented programming, and sketches the next one: carrier classes. a carrier class declares a component list, like a record, and gets the matching API (accessors, a constructor, a deconstruction pattern, reconstruction with with), but without records' restrictions: it can be extended, its fields can be mutable, and its representation doesn't have to match its components one to one. it's explicitly exploratory: no syntax, no JEP, no release.
the with expression for records. a candidate since late 2023, last updated in april 2024, and not targeted to any release.
- Amber ships small language features through previews, and previews can be withdrawn.
- derived record creation (
with) is a JEP candidate since 2023, not targeted to any release (as of october 2026). - string templates: previewed in 21 and 22, withdrawn in 2024, gone from 23.
\{is a compile error now. - primitive patterns match only when a conversion is exact. fifth preview in jdk 27.
- carrier classes, a generalization of records, are the next arc. a design note, not a JEP.