I work with immutable classes quite a lot. This means I also put final variables in abstract base classes. Not using final there will make the analyzer warn about missing setters in class implementations. Adding a dummy constructor is useless because I don't use it anywhere (I implement the abstract class, I don't extend it, in this case that has to do with the limits of the rpc package which cannot print fields from super classes). This means I miss some code coverage which I try to get at 100% in important projects.
I can of course ignore the analyzer warning about an uninitialized final in the abstract class, but I was wondering if this is by design behavior. Abstract classes should not be instantiated directly anyway.
My recommendation: If the abstract class is (intended as) an interface — you implement it and don't extend it — then use an abstract getter, instead of a final field, to declare that there is a getter in the interface.
If it is a base class, then you extend the class and inherit the field, and then it needs to be initialized correctly, so you need a constructor.
Otherwise, you actually do have uncovered code in your program - the implicit getter function of the final field is never called.
The analyzer doesn't have a choice here - the language specification says:
Each final instance variable f declared in the immediately enclosing class must have an initializer in k’s initializer list unless it has already been initialized by one of the following means:
• Initialization at the declaration of f.
• Initialization by means of an initializing formal of k.
or a static warning occurs
You could argue that this is a requirement on constructors, and you don't have any constructors, but it also applies to the default constructor added when you don't write a constructor yourself.
For me the getter is a good solution here. Thanks, that didn't cross my mind when I was working on it.
Closing the issue as you seem to have a solution, if this is still a problem please reopen it.
Most helpful comment
My recommendation: If the abstract class is (intended as) an interface — you implement it and don't extend it — then use an abstract getter, instead of a final field, to declare that there is a getter in the interface.
If it is a base class, then you extend the class and inherit the field, and then it needs to be initialized correctly, so you need a constructor.
Otherwise, you actually do have uncovered code in your program - the implicit getter function of the final field is never called.
The analyzer doesn't have a choice here - the language specification says:
You could argue that this is a requirement on constructors, and you don't have any constructors, but it also applies to the default constructor added when you don't write a constructor yourself.