java compilation_error ai_generated true

error: illegal combination of modifiers: 'abstract' and 'final' for a record

ID: java/invalid-modifier-in-record

Also available as: JSON · Markdown · 中文
95%Fix Rate
85%Confidence
1Evidence
2024-03-12First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Java 16+ active
Java 17 active
Java 21 active

Root Cause

Java records are implicitly final and cannot be abstract, so declaring a record with both abstract and final modifiers is illegal.

generic

中文

Java 记录类型隐式是 final 的,不能是 abstract,因此同时声明 abstract 和 final 修饰符是非法操作。

Official Documentation

https://docs.oracle.com/en/java/javase/17/language/records.html

Workarounds

  1. 95% success Remove both 'abstract' and 'final' from the record declaration. A record is implicitly final and cannot be abstract, so simply declare: `public record MyRecord(int x) { }`
    Remove both 'abstract' and 'final' from the record declaration. A record is implicitly final and cannot be abstract, so simply declare: `public record MyRecord(int x) { }`
  2. 85% success If you need abstraction, convert the record to a regular class with fields and methods, and implement equals/hashCode/toString manually.
    If you need abstraction, convert the record to a regular class with fields and methods, and implement equals/hashCode/toString manually.
  3. 80% success Use an interface with default methods and a record implementing that interface to achieve abstraction without subclassing.
    Use an interface with default methods and a record implementing that interface to achieve abstraction without subclassing.

中文步骤

  1. 从记录声明中移除 'abstract' 和 'final' 修饰符。记录隐式是 final 的,不能是 abstract,只需声明:`public record MyRecord(int x) { }`
  2. 如果需要抽象,将记录转换为普通类,包含字段和方法,并手动实现 equals/hashCode/toString。
  3. 使用包含默认方法的接口,并由记录实现该接口,以实现抽象而不需要子类化。

Dead Ends

Common approaches that don't work:

  1. Remove the 'final' modifier from the record declaration. 90% fail

    Records are implicitly final; removing 'final' still leaves the record as final, but the abstract modifier remains, which is still illegal.

  2. Add 'abstract' to a non-record class and implement the record's methods manually. 70% fail

    This changes the design entirely and may break serialization or pattern matching that relies on the record's canonical constructor.

  3. Use 'sealed' modifier instead of 'abstract' to allow subclassing. 100% fail

    Sealed records are not supported in Java 17; the compiler will reject 'sealed' on records.