Java error: incompatible types: no instance(s) of type variable(s) T exist so that Optional<T> conforms to Iterable<AvailableLicence>

huangapple go评论83阅读模式
英文:

Java error: incompatible types: no instance(s) of type variable(s) T exist so that Optional<T> conforms to Iterable<AvailableLicence>

问题

通常我是一名C#开发者,但我正在尝试用Java编写一些代码(多年来的第一次),使用泛型来创建一个“Retry”方法,允许我使用lambda表达式来重试任何代码块。这是我的重试方法:

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的东西,比如OptionalSupplier,我不确定它们是否可能导致问题,尽管我已经阅读了它们的工作原理。有人能告诉我在这里我做错了什么吗?我觉得这可能是一个简单的语法问题,我可能遗漏了。

英文:

Normally I'm a C# developer, but I'm trying to write some code in Java (first time in years) that uses generics to create a 'Retry' method that allows me to use a lambda expression to retry any block of code, basically. Here is my retry method:

public static &lt;T&gt; Optional&lt;T&gt; runWithRetry(final Supplier&lt;T&gt; t, int retryAttempts, long retryDelayInMilliseconds) throws InterruptedException {

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

		return Optional.empty();
	}

And I'm attempting to call this method like so:

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

but the Java compiler is throwing this error:

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

I think what this error is trying to tell me is that I am not specifying the type for &lt;T&gt; somewhere but I'm not entirely sure. I'm also combining some Java things like Optional and Supplier that I'm not sure if they could be causing the issue or not, despite having read up on how they work. Can anyone tell what I'm doing wrong here? I feel like it's a simple syntax issue I'm missing here.

答案1

得分: 1

以下是翻译好的部分:

我会让 runWithRetry() 的调用者不必处理检查过的 InterruptedException例如像这样&hellip;

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: 处理或记录警告 */ }
            }
        }
    }
    return retVal;
}

看看我在 我的演示中&hellip; 如何使用它:

...
Optional<Iterable<AvailableLicense>> licenses = Deduper.runWithRetry( ()->
    { return licensor.findAvailableLicenses(licenseOptions); }, 3, 5000 );

licenses.ifPresent(out::println);
...

因为我已经实现了 AvailableLicense.toString(),我的演示输出如下&hellip;:

[AvailableLicense[ type: To Kill!]]

Optional - The Mother of all Bikesheds 来自 @StuartMarks — 实现 Optional 的 Oracle 核心开发人员之一,强烈推荐 每个 使用 Optional 的人观看。

英文:

I would spare the caller of runWithRetry() having to handle the checked InterruptedException. For example like this&hellip;

public static &lt;T&gt; Optional&lt;T&gt; runWithRetry(final Supplier&lt;T&gt; t, int retryAttempts, long retryDelayInMilliseconds) {

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

See how I used that in my demo&hellip;

...
Optional&lt;Iterable&lt;AvailableLicense&gt;&gt; licenses = Deduper.runWithRetry( ()-&gt; 

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

Because I've implemented AvailableLicense.toString(), my demo outputs&hellip;

[AvailableLicense[ type: To Kill!]]

Optional - The Mother of all Bikesheds from @StuartMarks — one of the Oracle core devs that implemented Optional is recommended viewing for everybody using Optional.

huangapple
  • 本文由 发表于 2020年8月6日 10:03:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63275854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定