4

I use groovy and like the @Immutable annotation. The problem is, that this annotation does not only create constructors with the specified class fields, but also creates an empty constructor and allows the fields to partly stay null (or take a default value). I want to prevent this.

Example:

@Immutable class User { int age}

can be called like

User jasmin = new User(30)
println "I am ${jasmin.age} years old" // I am 30 years old

but also like

User james = new User() //Uhoh, I have no age
println "I am ${james.age} years old" // I am 0 years old - maybe not expected

My question is therefor: are there any annotations or other ways that prevent calling the empty constructor? Possibly throwing an exception when there is no age passed (or null passed for it) at runtime. Bonus points if I get eclipse IDE support so that an empty constructor call is complained by eclipse at compile time.

I did not find something like @NotNull for groovy, but for java i found different annotations as the ones in this question. Would using one of these a good idea? How to decide? Or is it better to write my own custom annotation - and can I get IDE help by doing that?

Community
  • 1
  • 1
valenterry
  • 757
  • 6
  • 21

1 Answers1

2

I agree with you; there should be an option in the @Immutable attribute to prevent the generation of the default constructor.

As far as a workaround, this probably isn't as elegant as you'd like, but I'm throwing this out there. If you create a mutable super type without a default constructor, you could extend it with an @Immutable version. For example:

import groovy.transform.*

class MutableUser {
    int age
    // defining an explicit constructor suppresses implicit no-args constructor
    MutableUser(int age) { 
        this.age = age 
    }
}

@Immutable
@InheritConstructors
class User extends MutableUser {
}

User jasmin = new User() // results in java.lang.NoSuchMethodError

But overall, this seems like an unnecessary amount of boilerplate just to suppress a no-arg constructor.

bdkosher
  • 5,753
  • 2
  • 33
  • 40
  • It also doesn't help me with null-value arguments. I want to achieve that no argument is `null`. It helps calling the empty constructor though, but also takes the help from the annotation having a map-constructor. I guess I need to dig more into annotations and AST transformation and create my own NotNull Annotation in groovy... – valenterry Nov 27 '14 at 09:33