I have a method
public static void injectConfiguration(@Configurable Object bean) {}
And I have a class which holds field
public class LauncherComponentsHolder { @Configurable public RoomDao roomDao;
And I have main class, where I call that method and pass him that:
LauncherComponentsHolder root = new LauncherComponentsHolder(); root.roomDao = new RoomDaoImpl(); root.guestDao = new GuestDaoImpl(); root.maintenanceDao = new MaintenanceDaoImpl(); ConfigInjector.injectConfiguration(root.roomDao); ConfigInjector.injectConfiguration(root.guestDao); ConfigInjector.injectConfiguration(root.maintenanceDao);
Problem is that the method accepts all the 3 parameters, (no warnings, errors, nothing) however only roomDao is annotated. Annotation itself:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER, ElementType.FIELD}) public @interface Configurable { }
How to make the restriction, so that injectConfiguration(@Configurable Object bean)
would accept only field (or class instance) annotated with Configurable
?
Advertisement
Answer
You can accomplish this by using an annotation processor. An example of such a tool is the Checker Framework. It enables you to write type annotations in your program, then it type-checks the type annotations at compile time. It issues a warning if the type annotations in your program are not consistent with one another.
The easiest way for you to implement the checking would be to use the Subtyping Checker.
Here is an example from its manual:
import myPackage.qual.Encrypted; ... public @Encrypted String encrypt(String text) { // ... } // Only send encrypted data! public void sendOverInternet(@Encrypted String msg) { // ... } void sendText() { // ... @Encrypted String ciphertext = encrypt(plaintext); sendOverInternet(ciphertext); // ... } void sendPassword() { String password = getUserPassword(); sendOverInternet(password); }
When you invoke javac
using a couple extra command-line arguments, javac
issues an error for the second invocation of sendOverInternet
but not the first one:
YourProgram.java:42: incompatible types. found : @PossiblyUnencrypted java.lang.String required: @Encrypted java.lang.String sendOverInternet(password); ^