我做错了什么,但不确定是什么. 试图制作一个查找 map ,为我提供我可以调用的函数.

问题的简单演示:

哦,我是.我是.

public class aa { /** doesn't matter for this example */}

♪Ab.Java♪

public class ab extends aa { /** doesn't matter for this example */}

Helper.java

public static short[] convert(ab foo)
{
  //doesn't matter but eventually returns a short[] i.e.
  return new short[5];
}

private interface aaConverterI
{
  public <T extends aa> short[] method(Function<T, short[]> in);
}

private static Map<String, aaConverterI> bar = new HashMap<>();
static
{
  bar.put("blah", Helper::convert);
}

编译器在Helper::Convert上说是The type Helper does not define convert(Function<T, short[]>) that is applicable here,The method put(String, Helper.aaConverterI) in the type Map<String, aaConverterI> is not applicable for the arguments (String, Helper::convert).

如果我添加一个

static Function<ab, short[]> blahFunction = Helper::convert;

没有抱怨,我可以改变把

bar.put("blah", blahFunction);

这使得编译器只会在PUT上抱怨The method put(String, Helper.aaConverterI) in the type Map<String, Helper.aaConverterI> is not applicable for the arguments (String, Function<ab, short[]>).

我错过了一些东西,但我不确定是什么.try 添加@FunctionalInterface来转换声明,但这并没有改变任何事情.

我遗漏了什么?谢谢!

推荐答案

此接口:

private interface aaConverterI
{
  public <T extends aa> short[] method(Function<T, short[]> in);
}

...满足用作功能接口的要求.要使方法引用与此函数接口兼容,其签名必须与aaConverterI.method()的签名匹配.也就是说,它接受匹配的Function作为其参数,并返回short[].

这一点:

public static short[] convert(ab foo)

一百零二个人有这样的签名.它接受ab类型的参数,而不是Function,尽管有其他所有考虑因素.这就解释了你的错误.


我怀疑你的意思是再定义aaConverterI个这样的人:

private interface aaConverterI
{
  public <T extends aa> short[] method(T in);
}

...但即便是这样,也行不通.aaConverterI.method()可以接受类型aa或其任意子类型的参数,但Helper.convert()不能接受类型aa的参数(例如).还要注意的是,aaConverter.method()实际上并没有从它的类型参数化中得到任何有用的东西.如果这是您真正想要的,那么您也可以手动执行擦除.

另一种更有可能的替代方案是使接口泛型,而不是方法:

private interface aaConverterI<T extends aa>
{
  public short[] method(T in);
}

...然后你可以写道:

private static Map<String, aaConverterI<? extends aa>> bar = new HashMap<>();
static
{
  bar.put("blah", Helper::convert);
}

,但这still个可能对您没有帮助,因为您会发现没有类型安全的方法来使用您从映射中拉回的任何方法.

Bottom line:

Java泛型不足以参数化您真正想要定义的Map,其中键是(比方说)Class<?>,值是类型aaConverterI<the-type-corresponding-to-the-key>.事实上,您最好的 Select 可能是手动擦除:

private interface aaConverterI
{
  public short[] method(aa in);
}

,您可以在其中编写具有完全相同签名的所有转换器方法,当然,还可以在其中使用CAST或Class.cast().

Java相关问答推荐

RDX触发ChoiceBox转换器(并按字符串值排序)

我可以在regex中的字符类中放置断言吗?

Java JAR环境(JRE)是否支持模块?

当切换javaFX场景时,stage的大小正在Minimize

为什么如果数组列表中有重复项,我的代码SOMETIMES不返回true?

Java中不同包中的类之间的配置共享

参数值[...]与预期类型java.util.Date不匹配

@ IdClass with @ Inheritance(策略= InheritanceType. SINGLE_TABLE)

如何创建一个2d自上而下的移动系统,其中移动,同时持有两个关键是可能的处理?

如何从JNI方法正确调用NSOpenPanel以在正确的线程上运行?

虚拟线程应该很快消亡吗?

解析方法";javax/imageio/metadata/IIOMetadata.getAsTree(Ljava/lang/String;)Lorg/w3c/dom/Node时加载约束冲突

AbstractList保证溢出到其他方法

Java在操作多个属性和锁定锁对象时使用同步和易失性

如何根据配置动态创建N个bean

在线程Java中调用Interrupt()之后调用Join()

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

从字节数组切换到JakartaMail org.springframework.mail.javamail.JavaMailSender InputStreamResource

[jdk21][Foreign Function&;Memory API]MemoryLayout::varHandle通过可变数组进行 struct 化的问题

如何在JSP中从select中获取值并将其放入另一个select