2017-12-07 10 views
2

私は、プロジェクトで起こったことを複製するための少しの例を用意します。私はそれを回避する方法を知っていますが、なぜそれがコンパイルされないのかは非常に不思議です。問題は最終的に返されます。私がメソッドpublic TestElement<?> test()の一般的なワイルドカードを使用しているときは、正確にはreturn response.map((element) -> mapAux(50L)).orElseGet(()-> orElseGetAux(20));という行です...なぜコンパイルされないのでしょうか?私は間違って何をしていますか?どんな手掛かり?mapとorElseGetで一般的なワイルドカードを使用するオプション

ありがとうございます!

Error:(33, 78) java: incompatible types: bad return type in lambda expression

FullTest.TestElement<capture#1 of ?> cannot be converted to FullTest.TestElement<capture#2> of ?> 

アップデート: -

public class FullTest { 
    public static class TestElement<T>{ 
    public T element; 

    public TestElement(T t) { 
     element = t; 
    } 
    } 

    public static <U> TestElement<U> createElement(U input) { 
    return new TestElement<>(input); 
    } 

    private TestElement<?> mapAux(Long element){ 
    return new TestElement<>(element); 
    } 

    private TestElement<?> orElseGetAux(Integer element){ 
    return new TestElement<>(element); 
    } 

    public TestElement<?> test(){ 
    Optional<Long> response = Optional.of(5L); 
    return response.map((element) -> mapAux(50L)).orElseGet(()-> orElseGetAux(20)); 
    } 
} 

Update 1では、エラー

私はのIntelliJの最後のバージョン上で、Javaの8を使用していますし、エラーがこれですインクルード2 - もう少しと回避策

ワイルドカードを使用するのは、異なるクラスのTesElement<>を返す必要があるからです(これは、LongとIntegerの例では唯一の方法です)。私はここで

私は避ける好む可能な回避策

(これは一例ですが、私は常にtrueを返し isPresent()を知っている)...他のオプションを開いています:

public TestElement<?> testWorkAround(){ 
    Optional<Long> response = Optional.of(5L); 
    TestElement<?> testElement; 
    if(response.isPresent()){ 
     testElement = mapAux(response.get()); 
    } 
    else{ 
     testElement = orElseGetAux(20); 
    } 
    return testElement; 
    } 
+0

@rgettmanフィードバックをいただきありがとうございます。私は、コンパイラのエラーメッセージを含める。 – JTejedor

答えて

1

public TestElement<?> test(){ 
    Optional<Long> response = Optional.of(5L); 
    Optional< TestElement<?> > opResult = response.map((element) -> mapAux(50L)); 

    TestElement<?> result = opResult.orElseGet(() -> orElseGetAux(20L)); 

    return result; 
} 
+0

このスニペットで私は次のエラーを受け取ります: 'エラー:(35、68)java:互換性のない型:longをjava.lang.Integerに変換できません。 ' – JTejedor

+0

それはあなたが呼んでいる方法でなければなりません。上記のコードは私の1.8.0_112コンパイラで問題なくコンパイルされます。 – tsolakp

+0

私は混乱がどこにあるのかと思う。本当にごめんなさい。数分前に行った最後の修正を見てください。私は 'orElseGetAux(Integer)'のメソッド 'orElseGetAux(Long)'を変更しました。しかし、リテラルが整数(Lのリテラルを消去している)であることを示すと、うまく動作します。しかし、同じ行でコードがコンパイルされないので、私はまだ混乱しています。 – JTejedor

1

ラムダ(element) -> mapAux(50L)mapへのあなたの呼び出しラムダ式が返すもののOptionalを返します。つまり、Optional<TestElement<?>>です。後でorElseGetに電話すると、TestElement<?>を返すラムダ式が使用されます。

ただし、1つのワイルドカードが別のワイルドカードと一致するという保証はありません。ワイルドカードは特定の未知の型を表すため、コンパイラは一致しないとみなします。

The method orElseGet(Supplier<? extends Main.TestElement<capture#1-of ?>>) in the type Optional<Main.TestElement<capture#1-of ?>> is not applicable for the arguments (() -> {}) 
Type mismatch: cannot convert from Main.TestElement<capture#3-of ?> to Main.TestElement<capture#1-of ?> 

これはコンパイルするために取得するには、型推論はその事と試合を行うことができますので、あなたがそれらのワイルドカードを排除する必要があります。これは、コンパイルエラーを得ることを意味します。次のいずれか

  1. はあなたのmapAuxorElseGetAuxメソッドを作成し、両方のTestElement<Long>を返します。

    private TestElement<Long> mapAux(Long element) 
    private TestElement<Long> orElseGetAux(Long element) 
    
  2. あるいは、Tは同じTが外出さに行くように、これらの2つの方法は、一般的な作り。これをしないのはなぜ

    private <T> TestElement<T> mapAux(T element) 
    private <T> TestElement<T> orElseGetAux(T element) 
    
+0

あなたの返事をありがとうございますが、 '.map'と' orElseGet'のdifferentsクラスのTestElementを返す必要がある場合はどうなりますか?この新しい側面も含めるように質問を更新します。 – JTejedor

関連する問題