Java ошибка: несовместимые типы: не существует экземпляров переменной (ов) типа T, поэтому Optional <T>соответствует Iterable <AvailableLicence> - PullRequest
1 голос
/ 06 августа 2020

Обычно я разработчик C#, но я пытаюсь написать код на Java (впервые за много лет), который использует дженерики для создания метода Retry, который позволяет мне использовать лямбда-выражение. в основном, чтобы повторить попытку любого блока кода. Вот мой метод повтора:

public static <T> Optional<T> runWithRetry(final Supplier<T> t, int retryAttempts, long retryDelayInMilliseconds) throws InterruptedException {

        for(int retry = retryAttempts; retry >= 0; retry--) {
            try{
                return Optional.of(t.get());
            }
            catch(Exception e) {
                if(retry == 0) {
                    throw e;
                } else if (retryDelayInMilliseconds > 0) {
                    Thread.sleep(retryDelayInMilliseconds);
                }
            }
        }

        return Optional.empty();
    }

И я пытаюсь вызвать этот метод следующим образом:

Iterable<AvailableLicence> licences = Helpers.runWithRetry(() -> {
            return licensor.findAvailableLicences(licenseOptions);
        }, 3, 5000);

, но компилятор Java выдает эту ошибку:

error: incompatible types: no instance(s) of type variable(s) T exist so that Optional<T> conforms to Iterable<AvailableLicence>
                Iterable<AvailableLicence> licences = Helpers.runWithRetry(() -> {
                                                                          ^
  where T is a type-variable:
    T extends Object declared in method <T>runWithRetry(Supplier<T>,int,long)

Я думаю, что эта ошибка пытается сказать мне, что я где-то не указываю тип для <T>, но я не совсем уверен. Я также комбинирую некоторые Java вещи, такие как Optional и Supplier, и я не уверен, могут ли они вызывать проблему, несмотря на то, что я читал, как они работают. Кто-нибудь может сказать, что я здесь делаю не так? Мне кажется, что мне здесь не хватает простого синтаксиса.

1 Ответ

1 голос
/ 06 августа 2020

Я бы избавил вызывающего runWithRetry() от необходимости обрабатывать проверенные InterruptedException. Например, вот так

public static <T> Optional<T> runWithRetry(final Supplier<T> t, int retryAttempts, long retryDelayInMilliseconds) {

    return handleSleep(t, retryAttempts, retryDelayInMilliseconds);
}
    
private static <T> Optional<T> handleSleep(final Supplier<T> t, int retryAttempts, long retryDelayInMilliseconds){ 
        
    Optional<T> retVal = Optional.empty();
        
    for(int retry = retryAttempts; retry >= 0; retry--) {
        try{
            retVal = Optional.of(t.get());
        }
        catch(Exception e) {
            if(retry == 0) {
                throw e;
            } else if (retryDelayInMilliseconds > 0) {
                  try{
                      Thread.sleep(retryDelayInMilliseconds);
                  } catch(InterruptedException ie){ /*TODO: Handle or log warning */ }
            }
        }
    }
    return retVal;
}

Посмотрите, как я использовал в своей демонстрации

...
Optional<Iterable<AvailableLicense>> licenses = Deduper.runWithRetry( ()-> 

    { return licensor.findAvailableLicenses(licenseOptions); }, 3, 5000 );
    
licenses.ifPresent(out::println);
...

Поскольку я реализовал AvailableLicense.toString(), мои демонстрационные выходы…

[AvailableLicense[ type: To Kill!]]

Необязательно - Мать всех байкехедов от @StuartMarks - одна из Oracle основных разработчиков, реализовавших Optional, рекомендуется для просмотра всем с использованием Optional.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...