有没有办法根据Annotation类型指定Generic类型?

时间:2018-03-20 20:03:33

标签: java generics java-8

我有一个用例,我将在列表中添加不同的功能接口。我想在这个列表中使用泛型,这样我就只能添加明确注释为FunctionInterface的接口的实现。我尝试过类似下面的内容: -

class GenericsInJavaAnnotations {

    public static void main(String[] args) {

        Function<Product, Info> function = (Product p) -> p.getInfo();
        Supplier<String> supplier = () -> "test";
        List<? super FunctionalInterface> functions = new ArrayList<>();
        functions.add(function);
        functions.add(supplier);
    }
}

class Product {
    private Info info = new Info();

    public Info getInfo() {
        return info;
    }
}

class Info {

}

使用List<? super FunctionalInterface>以及List<? extends FunctionalInterface>会出错。

Error:(15, 18) java: no suitable method found for add(java.util.function.Function<java8.Product,java8.Info>)
    method java.util.Collection.add(capture#1 of ? super java.lang.FunctionalInterface) is not applicable
      (argument mismatch; java.util.function.Function<java8.Product,java8.Info> cannot be converted to capture#1 of ? super java.lang.FunctionalInterface)
    method java.util.List.add(capture#1 of ? super java.lang.FunctionalInterface) is not applicable
      (argument mismatch; java.util.function.Function<java8.Product,java8.Info> cannot be converted to capture#1 of ? super java.lang.FunctionalInterface)
Error:(16, 18) java: no suitable method found for add(java.util.function.Supplier<java.lang.String>)
    method java.util.Collection.add(capture#2 of ? super java.lang.FunctionalInterface) is not applicable
      (argument mismatch; java.util.function.Supplier<java.lang.String> cannot be converted to capture#2 of ? super java.lang.FunctionalInterface)
    method java.util.List.add(capture#2 of ? super java.lang.FunctionalInterface) is not applicable
      (argument mismatch; java.util.function.Supplier<java.lang.String> cannot be converted to capture#2 of ? super java.lang.FunctionalInterface)

我非常了解泛型并且同意super和extends具有不同的含义,并且没有涵盖由注释标记的类或接口。

有人知道任何变通方法或实际解决方案吗?或者它是我们在未来版本的Java中应该期待的一个可能的功能?

1 个答案:

答案 0 :(得分:1)

您会混淆类型和对象(也就是类的实例)。 List能够存储对象并且您在“列表中添加不同的功能接口”的意图不合适,因为您没有添加接口列表,但对象

你甚至不能说你想要存储功能接口的实例,就像在Java中一样,通常没有接口实例。只有 classes 实现接口的实例,但这些类没有@FunctionalInterface注释,事实上,这个注释对于类是无效的。

换句话说,当你写

Function<Product, Info> function = (Product p) -> p.getInfo();
Supplier<String> supplier = () -> "test";

你得到没有注释的故意未指定的实现类的对象,甚至无法在编译时确定它。
好吧,在@FunctionalInterface的特定情况下,我们知道他们不会拥有它,因为它会违反注释的语义,但通常,当类或接口有注释时,不需要子类或者实现类也有这个注释。

属性中甚至没有任何有用的语义“此类实现了具有@FunctionalInterface注释的接口”。

我可以写

interface NotEvenRemotelyFunctional extends Supplier<String> {
    default String get() { return ""; }
    void foo();
    void bar();
}
static class SomeOrdinaryClass implements NotEvenRemotelyFunctional {
    public void foo() { System.exit(0); }
    public void bar() { System.out.println("hello"); }
}
Supplier<String> sup = () -> "test";
// your intention is that your list accepts the object referenced by sup
SomeOrdinaryClass obj = new SomeOrdinaryClass();
// but not that object referenced by obj... I supose
sup = obj;
// except when it is referenced by sup?

那么期望的结果是什么?

  • 仅接受在超类型层次结构中某处具有¹功能接口的类型的实例?
    ¹或至少一个
  • 在我们将实例添加到所有类型信息丢失的列表之前,只有当它们被分配到功能接口类型的变量时才接受实例?

没有任何意义。

相关问题