Java泛型、类型擦除、通配符和函数<&燃气轮机;产生不兼容的类型

Java泛型、类型擦除、通配符和函数<&燃气轮机;产生不兼容的类型,java,generics,java-8,wildcard,Java,Generics,Java 8,Wildcard,还有一个菜鸟问题,对不起 让我们考虑下面的代码: public class ExceptionHandler { // simple internal manager @FunctionalInterface private interface ExceptionManager<D extends Exception> { int getErrorCode(D e, WebRequest request, H

还有一个菜鸟问题,对不起

让我们考虑下面的代码:

public class ExceptionHandler {

   // simple internal manager
   @FunctionalInterface
   private interface ExceptionManager<D extends Exception> {
     int getErrorCode(D e, WebRequest request, 
                      HttpServletRequest servletRequest);
   }

   // One field, just for the illustration 
   // (TypeMismatchException came from spring framework)
   private ExceptionManager<TypeMismatchException> tmeManager = 
      (ex, req, servletRequest) -> {
         int errorCode = 0;
         // ...
         return errorCode;
      };

   // A simple "factory" for an ExceptionManager
   private Function<? extends Exception, 
          Optional<ExceptionManager<? extends Exception>>> factory = (ex) -> {
      if(ex instanceof TypeMismatchException) {
         return Optional.of(tmeManager);
      }
      /* ... */
      return Optional.empty();
   };

   // global  exception manager
   private ExceptionManager<? extends Exception> defaultExceptionManager =
      (exception, request, servletRequest) -> {

         final Optional<ExceptionManager<? extends Exception>> manager = 
                         factory.apply(exception);

         if(manager.isPresent()) {
            return manager.get()
                    .getErrorCode(exception, request, servletRequest);
         }
         return 1;
      };
}
在思考和阅读了这个问题之后,java似乎执行了类型擦除(为了jvm向后兼容性),因此代码:

private ExceptionManager<? extends Exception> defaultExceptionManager = 
                   (exception, request, servletRequest) -> { /* ... */ }
应该成为

private interface ExceptionManager<Exception> { /* ... */ }
此调用的结果是

Error:(154, 63) java: incompatible types:
      org.springframework.beans.TypeMismatchException
      cannot be converted to capture#3 of ? extends java.lang.Exception
对不起,这个问题太长了,谢谢你的阅读和回答!
关于

当您声明像
function这样的函数时,我认为这里的第一个答案描述了如何找出错误:如果在赋值之前显式地强制转换lambda会发生什么
ExceptionManagerTanks为两个回复@JohnB(您指出的帖子非常有趣,以前没有登上过)。对于第二点,演员阵容不会改变行为。对于第二点,我希望能够在接口中保留泛型,这样我就可以编写管理器(例如:
ExceptionManager-tmeManager
),而无需在实现内部强制转换任何内容。注意,代码的结构主要用于学习如何处理java8的一些特性(函数、lambda和泛型)。再次感谢您的时间和回答。
private interface ExceptionManager<D extends Exception> { /* ... */ }
private interface ExceptionManager<Exception> { /* ... */ }
protected ResponseEntity<Object> handleTypeMismatch(final TypeMismatchException ex,
   final HttpHeaders headers, final HttpStatus status,
   final WebRequest request) {
   /* ... */
   int errorCode = defaultExceptionManager.getErrorCode(ex, request, servletRequest);
}
Error:(154, 63) java: incompatible types:
      org.springframework.beans.TypeMismatchException
      cannot be converted to capture#3 of ? extends java.lang.Exception
public class ExceptionHandler {
    // simple internal manager
    @FunctionalInterface
    private interface ExceptionManager<D extends Exception> {
        int getErrorCode(D e, WebRequest request, HttpServletRequest servletRequest);
    }
    // One field, just for the illustration 
    private static ExceptionManager<TypeMismatchException> tmeManager = 
       (ex, req, servletRequest) -> {
          int errorCode = 0;
          // ...
          return errorCode;
       };

    // A simple "factory" for an ExceptionManager
    private static <E extends Exception> Optional<ExceptionManager<E>> factory(E ex) {
        if(ex instanceof TypeMismatchException) {
            // unavoidable unchecked operation
            @SuppressWarnings("unchecked") ExceptionManager<E> em
                                         = (ExceptionManager<E>)tmeManager;
            return Optional.of(em);
        }
        /* ... */
        return Optional.empty();
    }
    // global  exception manager
    private ExceptionManager<Exception> defaultExceptionManager
                                      = ExceptionHandler::handleDefault;

    static <E extends Exception> int handleDefault(E exception, WebRequest request, 
                                                   HttpServletRequest servletRequest) {
        final Optional<ExceptionManager<E>> manager = factory(exception);
        return manager.map(em -> em.getErrorCode(exception, request, servletRequest))
                      .orElse(1);
    }
}