Что случилось с полиморфизмом для классов, сгенерированных jOOQ? - PullRequest
2 голосов
/ 19 марта 2019

Давайте возьмем запрос от моего другого вопроса :

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 ]

3 голосов
/ 19 марта 2019

Это просто , как дженерики работают в Java .

Это также не компилируется с тем же сообщением об ошибке:

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

Возможно, вы захотите напечатать вашу переменную что-то вроде SelectConditionStep<? extends Record> query.Таким образом, вы сообщаете компилятору, что любой подкласс Record является приемлемым (в противном случае это не так).Если вы сделаете это, вы также получите Result<? extends Record> в конце, однако, больше не будет что-то небезопасно в количестве и форме столбцов.

2 голосов
/ 20 марта 2019

Использование подстановочных знаков для <R extends Record>

Хотя правильный ответ на ваш конкретный вопрос уже дан Тило , я думаю, что вы хотели сделать этопросто не пишите полную подпись этого промежуточного типа, потому что она вам не нужна и потому что она утомительна.Вы можете использовать подстановочный знак:

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

Поскольку в API jOOQ тип <R extends Record> ограничен Record, этот подстановочный знак все еще неявно ограничен также Record, поэтому, в принципе,вышеприведенное неявно совпадает с:

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

Это означает, что когда вы повторяете результат, вы все равно можете присвоить элементам Record:

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

Caveat: Unions,коррелированные подзапросы и т. д.

Тип <R extends Record> используется в нескольких элементах API, включая объединения, коррелированные подзапросы и т. д. Если вы используете подстановочный знак, вы не можете использовать свой запрос как подзапрос в этом синтаксисе.elements

Дополнительное примечание относительно типов XYZStep jOOQ

В качестве дополнительного примечания обратите внимание, что рекомендуется избегать ссылок на типы XYZStep jOOQ.Присвойте свой запрос Select<?> или ResultQuery<?> вместо:

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