首页 > 解决方案 > 模棱两可的方法调用未通过强制转换解决

问题描述

我正在尝试做类似的事情:

t.set(field("ColumnName"), select(max(field("ColumnName"))).from("TableName"));

但我收到以下编译错误:

    Ambiguous method call, Both
    set(Field,Object)                    in InsertSetStep and
    set(Field,Select<? extends Record1>) in InsertSetStep match

我试图通过强制转换来解决歧义,但我仍然收到同样的错误

Select<? extends Record1> sq = select(max(field("ColumnName"))).from("TableName");
t.set( field("ColumnName"), (Select<? extends Record1>)sq );

我有几个问题:

  1. 为什么强制转换不能解决这种情况下的歧义?(我尝试过强制转换(Object),这确实解决了歧义)
  2. 我有办法解决歧义吗?

标签: javagenericsjavacjooqoverloading

解决方案


这是 Java 语言和各种编译器的一个非常不幸但指定的行为。虽然预泛型,采用Select类型的方法将更具体地用于您的特定调用,但一旦涉及泛型,情况就不再如此。原理可以在这里看到

像 jOOQ 这样的通用且重载的 API 并没有太多可以做的事情,但是作为用户,您可以。在这种情况下,您必须避免绑定<T>Object,无论是使用代码生成器,还是手动传递数据类型:

// Assuming this is an INTEGER type
t.set(
    field("ColumnName", SQLDataType.INTEGER), 
    select(max(field("ColumnName", SQLDataType.INTEGER))).from("TableName"));

或者,您开始将列引用存储在一些静态变量中,例如:

Field<Integer> COLUMN_NAME = field("ColumnName", SQLDataType.INTEGER);

// And then:
t.set(COLUMN_NAME, select(max(COLUMN_NAME)).from("TableName"));

使用代码生成器

请注意,当您使用代码生成器时,这几乎不是问题,在这种情况下,您将特定类型信息绑定到引用的<T>类型Field<T>,在这种情况下,重载将不再适用。

出于这个原因(以及许多其他原因),我真的建议您使用代码生成器


推荐阅读