2015-11-04 2 views
8

Использование Guava's ClassPath Я пытаюсь инициализировать классы, расположенные в определенном пакете, но я хочу использовать конструктор для инициализации, поскольку это не распространяется на исключения. Так это то, что я работал, чтобы получить конструкторы:Ошибка при циклическом интерфейсе при использовании 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) 
    ); 

Однако это дает ошибку в InteliJ просто указав Циклический интерфейс. Я думаю, что я знаю, что такое циклический интерфейс, но я не уверен, почему это может вызвать эту ошибку. Насколько я знаю, пока известен тип возврата (для 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 - так что вы также можете использовать проверенные исключения и не ограничиваться сигнатурой в интерфейсе Stream, который не имеет предложения throw.

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);