使方法只接受带有特定注解的参数

Make method accept only parameter with particular annotation

我有办法

public static void injectConfiguration(@Configurable Object bean) {}

我有一个 class 包含字段

public class LauncherComponentsHolder {
@Configurable
public RoomDao roomDao;

我有 main class,我在其中调用该方法并传递给他:

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);

问题是该方法接受所有 3 个参数,(没有警告、错误,什么都没有)但是只有 roomDao 被注释。注释本身:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
public @interface Configurable {

}

如何进行限制,以便 injectConfiguration(@Configurable Object bean) 只接受用 Configurable 注释的字段(或 class 实例)?

您可以使用注释处理器来完成此操作。 这种工具的一个例子是 Checker Framework。 它使您能够在程序中编写类型注释,然后在编译时 type-checks 类型注释。如果程序中的类型注释彼此不一致,它会发出警告。

执行检查的最简单方法是使用 Subtyping Checker

这是其手册中的 example

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);
}

当您使用几个额外的 command-line 参数调用 javac 时,javac 会在第二次调用 sendOverInternet 而不是第一次调用时发出错误:

YourProgram.java:42: incompatible types.
found   : @PossiblyUnencrypted java.lang.String
required: @Encrypted java.lang.String
    sendOverInternet(password);
                     ^