Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const correctness in Java using Annotations?

Is there an existing library that allows me to annotate a Java method as @Const, so that the compiler (using apt I presume) will flag an error if it updates a field, or invokes a non-@Const method on a field; and annotate a parameter as @Const, so that the accepting method cannot invoke any of its non-@Const methods, or update any of its fields?

(Basically, trying to add const-correctness to Java using annotations; there are some obvious details not covered in the question above, such as assigning to/from a @Const-typed parameter, etc.)

I've found this: http://confluence.atlassian.com/pages/viewpage.action?pageId=182158080 but it seems like it's only available as part of IDEA.

Following a request for clarification below, here's sample code to show what I mean:

class Person {
  private String name;
  private String address;

  @Const public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  ... etc. for address
}

Now, if I define a method such as:

void processPerson(@Const Person p)

a line such as: p.getName() would be OK in processPerson, since getName was marked as a @Const method. But calling p.setName() from within processPerson would be flagged as an error.

Note that this is very different from final: if the parameter was defined as final Person p, any assignment to p would have been illegal, but it's still perfectly valid to modify what p refers to (either using p.setName(...) or even more directly, with p.name = ....

like image 445
M. Elkstein Avatar asked Feb 06 '11 09:02

M. Elkstein


2 Answers

  • JSR-305 supposedly does just about what you're looking for

  • Personally, I'd see if I can use Hibernate Validator - Bean Validation (JSR-303) for that. It's a wonderful little lib (doesn't depend on hibernate, it's small) and it does wonders to keeping your data clean. See the documentation.

  • A google guy also started Contracts for Java recently, but it might not be production quality yet.

like image 101
Geoffrey De Smet Avatar answered Nov 02 '22 06:11

Geoffrey De Smet


Take a look at the Checker Framework, which basically has checkers that try to detect software defects [JSR-305] via an extensible type annotation system [JSR-308].

It has an immutability checker (2 actually) which allows you to annotate code with immutability annotations like @Mutable, @Immutable, and @Readonly. This tool differentiates between an immutable instance and a read-only reference.

I love this framework and mainly use it for null checking, but I am trying to start using the immutability checker and interning checker more.

annotate a parameter as @Const, so that the accepting method cannot invoke any of its non-@Const methods, or update any of its fields?

Would look like:

void addFriend(@ReadOnly Friend friend) { this.friends.add(friend); }

allows me to annotate a Java method as @Const, so that the compiler (using apt I presume) will flag an error if it updates a field, or invokes a non-@Const method on a field; and

It would look like this for the example in the question:

public String getName(@ReadOnly Person this) {
  return name;
}

The @ReadOnly here indicates the receiver (the this instance whose method is being called) should NOT be modified. Despite the apparent extra parameter, the method is still called as usual:

@ReadOnly Person person = new Person();
person.getName();

like image 6
Bert F Avatar answered Nov 02 '22 06:11

Bert F