jOOQ生成的类的多态性发生了什么?

时间:2019-03-19 09:28:22

标签: java generics inheritance polymorphism jooq

让我们从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<Record1<String>>替换为SelectConditionStep<Record>,我会得到

  

不兼容的类型。

     

必填:SelectConditionStep<org.jooq.Record>

     

发现:SelectConditionStep<org.jooq.Record1<java.lang.String>>

但是...

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的实例视为Record的实例?

(是的,我开始质疑自己,直到需要检查自己是否完全不介意:https://ideone.com/0O4mOU

2 个答案:

答案 0 :(得分:3)

那只是how generics work in Java

这也不编译,带有相同的错误消息:

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

您可能想输入SelectConditionStep<? extends Record> query之类的变量。这样,您就告诉编译器Record的任何子类都是可以接受的(否则是不可以的)。如果这样做的话,即使在列的数量和形状上也不再是类型安全的了,但最后还会得到一个Result<? extends Record>

答案 1 :(得分:2)

<R extends Record>使用通配符

Thilo已为您的特定问题提供了正确的答案,但我认为您想做的只是不拼出该中间类型的整个类型签名,因为您不需要它,而且它很乏味。您可以使用通配符:

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

因为在整个jOOQ API中,<R extends Record>类型都受Record限制,所以该通配符也仍然受Record所限制,因此,原则上,上述内容是相同的为:

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

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

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

注意:联合,相关子查询等

<R extends Record>类型用于一些API元素,包括并集,相关的子查询等。如果使用通配符,则不能在这些语法元素中将查询用作子查询

关于jOOQ的XYZStep类型的注释

请注意,建议您尽量避免引用jOOQ的XYZStep类型。将查询分配给Select<?>ResultQuery<?>

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