【问题标题】:What happened to polymorphism for jOOQ-generated classes?jOOQ 生成的类的多态性发生了什么?
【发布时间】:2019-08-09 18:38:53
【问题描述】:

让我们从my other question获取查询:

SelectConditionStep<Record1<String>> query = create
        .select(AUTHOR.LASTNAME.as("AuthorName"))
            .from(
                    (
                            BOOK.leftOuterJoin(BOOK_AUTHOR).on(BOOK.ID.eq(BOOK_AUTHOR.BOOKID))
                    ).leftOuterJoin(AUTHOR).on(AUTHOR.ID.eq(BOOK_AUTHOR.AUTHORID))
            )
            .where(BOOK.ID.eq(1))
        ;

//when
Result<Record1<String>> result = query.fetch();

如果我尝试用SelectConditionStep&lt;Record&gt; 替换SelectConditionStep&lt;Record1&lt;String&gt;&gt;,我会得到

不兼容的类型。

必填:SelectConditionStep&lt;org.jooq.Record&gt;

找到:SelectConditionStep&lt;org.jooq.Record1&lt;java.lang.String&gt;&gt;

然而……

package org.jooq;

import javax.annotation.Generated;

/**
 * A model type for a records with degree <code>1</code>
 *
 * @see Row1
 * @author Lukas Eder
 */
@Generated("This class was generated using jOOQ-tools")
public interface Record1<T1> extends Record {...}

那么……什么给了?

除非我遗漏了一些非常明显的东西,否则我是否应该被允许将Record1 的实例视为Records 处理?

(是的,我开始质疑自己,以至于我需要检查自己是否完全没有精神:https://ideone.com/0O4mOU

【问题讨论】:

    标签: java generics inheritance polymorphism jooq


    【解决方案1】:

    那只是how generics work in Java

    这也不编译,同样的错误信息:

    ArrayList<Animal> x = new ArrayList<Dog>(); 
    ArrayList<List<String>> x = new ArrayList<ArrayList<String>>();
    

    您可能需要键入类似SelectConditionStep&lt;? extends Record&gt; query 的变量。这样,您告诉编译器Record 的任何子类都是可接受的(否则情况并非如此)。如果你这样做,你也会在最后得到一个Result&lt;? extends Record&gt;,但是,在列的数量和形状上不再是类型安全的。

    【讨论】:

    • 当我有一段时间没有使用它们时,我总是忘记一些非常基本的东西,这真是令人惊讶。 -.- 谢谢。
    【解决方案2】:

    &lt;R extends Record&gt; 使用通配符

    虽然Thilo 已经给出了您的特定问题的正确答案,但我相信您想要做的只是不拼出这个中间类型的整个类型签名,因为您不需要它,因为它很乏味。您可以使用通配符:

    SelectConditionStep<?> query = ...;
    Result<?> result = query.fetch();
    

    因为在整个 jOOQ API 中,&lt;R extends Record&gt; 类型以 Record 为界,该通配符仍隐式地以Record 为界,因此原则上,上述内容与以下内容相同:

    SelectConditionStep<? extends Record> query = ...;
    Result<? extends Record> result = query.fetch();
    

    这意味着当你迭代结果时,你仍然可以将元素分配给Record

    for (Record record : result) { ... }
    

    警告:联合、相关子查询等

    &lt;R extends Record&gt; 类型用于一些 API 元素,包括联合、相关子查询等。如果使用通配符,则不能将查询用作这些语法元素中的子查询

    关于 jOOQ 的 XYZStep 类型的附注

    作为旁注,请注意建议您尽量避免引用 jOOQ 的 XYZStep 类型。将您的查询分配给Select&lt;?&gt;ResultQuery&lt;?&gt;

    Select<?> query = ...;
    Result<?> result = query.fetch();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      • 2012-06-02
      • 2021-12-29
      • 2021-01-27
      • 2021-01-22
      • 1970-01-01
      • 2011-03-03
      相关资源
      最近更新 更多