2015-11-04 8 views
8

使用Guava's ClassPath特定のパッケージにあるクラスを初期化しようとしていますが、コンストラクタを使用して例外を伝播しないように初期化します。しかし、これは単に巡回インタフェースを述べるInteliJでエラーが発生しますorElseThrowを使用したときの循環インタフェースエラー

ClassPath.from(classLoader).getTopLevelClasses("test.package").stream() 
    .map(ClassPath.ClassInfo::load) 
    .map(Class::getConstructors) 
    .map(Arrays::stream) 
    .map(constructorStream -> constructorStream 
     .filter(constructor -> constructor.getParameterCount() == 0) 
     .findAny() 
     .orElseThrow(RuntimeException::new) 
    ); 

:だからこれは私がコンストラクタを取得するために働いたものです。私はCyclicインターフェイスが何であるか知っていると思うが、なぜこのエラーが発生するのか分からない。私の知る限り、戻り値の型がわかっている限り(orElseThrowの場合は戻り値がConstructor<?>である)、チェックされていない例外をスローすると問題ありません。 orElse(null)を使用するとエラーが消えます。ここで何が起こっているのですか?投げたいRuntimeExceptionをどうやって投げることができますか?

+1

'orElseThrow'の接頭辞に特定の型を付けるとどうなりますか? '。 orElseThrow(RuntimeException :: new)' – RealSkeptic

+0

エラーは削除され、意図したとおりに動作します。どうして?提供された例外によって 'X'は既に定義されていてはなりませんか? – danthonywalker

+1

私はあなたが型推論を非常に厳密にしないコンパイラを使用していると思います。 Eclipseでは明示的な型引数なしで動作します。 Oracleの 'javac'では、報告されていない例外について文句を言います。 – RealSkeptic

答えて

0

ランタイム例外は、マップラムダ内からスローされます。実際の例外はStream API内で処理できます。

これを避けるには、flatMapメソッドを使用して、現在のストリームをflatMapメソッドに提供された結合ストリームに置き換えることができます。これは、ストリームを結合するときによく使用されます。 adam bien's example on flatmap.

この例では、例外はストリーミングAPIを通過する必要はありません。チェックされた例外も使用でき、throws節のないStreamインターフェイスのシグネチャによって制限されることはありません。

ClassPath.from(classloader).getTopLevelClasses("test.package").stream() 
      .map(ClassPath.ClassInfo::load) 
      .map(Class::getConstructors) 
      .flatMap(Arrays::stream) 
      .filter(constructor -> constructor.getParameterCount() == 0) 
        .findAny() 
        .orElseThrow(RuntimeException::new); 
関連する問題