当前位置: 首页 > 知识库问答 >
问题:

Java8中异常类型推理的一个特点

上官兴昌
2023-03-14

在这个网站上为另一个答案编写代码时,我遇到了这样一个特点:

static void testSneaky() {
  final Exception e = new Exception();
  sneakyThrow(e);    //no problems here
  nonSneakyThrow(e); //ERRROR: Unhandled exception: java.lang.Exception
}

@SuppressWarnings("unchecked")
static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
  throw (T) t;
}

static <T extends Throwable> void nonSneakyThrow(T t) throws T {
  throw t;
}

首先,我很困惑为什么sneakythrow调用对编译器来说是可以的。当没有提到任何未检查的异常类型时,它推断出t的可能类型是什么?

其次,既然这是可行的,那么编译器为什么要抱怨nonsneakythrow调用呢?他们看起来很像。

共有1个答案

司空瑾瑜
2023-03-14

sneakythrow的T被推断为runtimeexception。这可以从关于类型推断的langauge规范(http://docs.oracle.com/javase/specs/jls/se8/html/jls-18.html)中得到遵循

首先,在第18.1.3节中有一个注释:

throwsa表单的一个范围纯粹是信息性的:它指示解析优化A的实例化,以便在可能的情况下,它不是检查的异常类型。

...否则,如果绑定集包含throws,并且ai的正确上界至多为exceptionthrowableobject,则Ti=runtimeexception

这种情况适用于sneakythrow-唯一的上限是throwable,因此根据规范,t被推断为runtimeexception,因此它可以编译。方法的主体是无关紧要的-未经检查的强制转换在运行时成功,因为它实际上并没有发生,留下一个可以击败编译时检查的异常系统的方法。

nonsneakythrow不编译,因为该方法的t具有exception的下限(即t必须是exceptionexception本身的超类型),由于调用它的类型,它是检查异常,因此t被推断为exception

 类似资料:
  • 问题内容: 在此站点上为另一个答案编写代码时,我遇到了这种特殊性: 首先,我很困惑为什么对编译器的调用正常。当未提及任何未经检查的异常类型时,它推断出什么可能的类型? 其次,接受这一工作原理后,为什么编译器会在调用中抱怨?他们看起来非常相似。 问题答案: 的T 推断为。可以从有关类型推断的语言规范(http://docs.oracle.com/javase/specs/jls/se8/html/j

  • 主要内容:1 Java8 类型推断的介绍,2 Java8 类型推断的案例1,3 Java8 类型推断的案例21 Java8 类型推断的介绍 类型推断是Java的一项功能,它使编译器可以查看每个方法调用和相应的声明以确定参数的类型。 Java在Java 8中提供了类型推断的改进版本。 1.1 Java8以前 在下面的声明中,我们在一侧提到了arraylist的类型。这种方法是在Java 7中引入的。在这里,您可以将第二面留为<>,并且编译器将通过引用变量的类型来推断其类型。 1.2 Java8以后

  • 本文向大家介绍详谈Java8新特性泛型的类型推导,包括了详谈Java8新特性泛型的类型推导的使用技巧和注意事项,需要的朋友参考一下 1. 泛型究竟是什么?   在讨论类型推导(type inference)之前,必须回顾一下什么是泛型(Generic).泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。通俗点将就是“类型的变量”。这种类型变量可

  • 我正在构建一个颤振应用程序,我必须解析api中的一些数据,我设置了所有内容,但我收到了这个错误,我不知道为什么,我是颤振新手,任何帮助都将不胜感激。谢谢。 生成的错误 这是我的api响应示例 这就是我处理数据的方式 这是模型课

  • 我有一个资源类,它本身与内部服务进行对话。此资源充当服务的rest API。服务层可以抛出意外异常,因此资源应该处理那些已处理的意外异常并将其记录下来。我正在使用dropwizard框架,它反过来又使用jersey。事情是这样的。 这里的问题是,我必须对每个REST apiendpoint执行完全相同的异常处理。我可以为这个特定的资源进行某种类型的异常映射,以便将所有的处理逻辑和日志记录放在那里吗

  • 我正在运行一个简单的代码来启动Firefox浏览器。在Visual Studio中运行它。代码如下: 获取错误异常为: “System”类型的未处理异常。WebDriver中发生“InvalidOperationException”。dll其他信息:为安装功能转发新的虚拟机会话空池时出错[{browserName=firefox,version=firefox,platform=ANY}] 谁能告