I'm having a method that accepts, for example, two long primitives. How can I add checks to prevent the accidental swapping of parameters?
Something like this should be detected.
public void startSomethingElse(@AccountIdParam long accountId, @BalanceParam long balance) {
System.out.println("Account " + accountId + " balance " + balance);
}
public void startOfSomething() {
@AccountIdParam long accountId = 1;
@BalanceParam long balance = 100;
startSomethingElse(balance, accountId);
}
Using CheckerFramework, I could create custom qualifiers like this:
@SubtypeOf({})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface AccountIdParam {}
@SubtypeOf({})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface BalanceParam {}
But that won't work without creating hierarchy so I need to do something like this which also wouldn't work because of two leaf nodes:
@SubtypeOf({Unqualified.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface AccountIdParam {}
@SubtypeOf({Unqualified.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface BalanceParam {}
@DefaultQualifierInHierarchy
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({})
public @interface Unqualified {}
How would you do it?
Couple of constraints:
I need to use primitives so subclassing Java objects isn't a option.
I need to have compile time check, not run time.