在此站点上为另一个答案编写代码时,我遇到了这种特殊性:
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
调用中抱怨?他们看起来非常相似。
的T
sneakyThrow
推断为RuntimeException
。可以从有关类型推断的语言规范(http://docs.oracle.com/javase/specs/jls/se8/html/jls-18.html)中遵循此规则。
首先,在第18.1.3节中有一条注释:
形式的边界
throws α
纯粹是信息性的:它指导分辨率优化α的实例化,因此,如果可能的话,它不是经过检查的异常类型。
这没有任何影响,但是它使我们指向了“解析”部分(18.4),该部分获得了有关特殊情况下的推断异常类型的更多信息:
......否则,如果绑定集包含
throws αi
,和α我的正常上限的,顶多Exception
,Throwable
和Object
,然后TI =RuntimeException
。
这种情况适用于sneakyThrow
-唯一的上限是Throwable
,因此根据规范T
推断为RuntimeException
,因此可以编译。该方法的主体是无关紧要的-
未经检查的强制转换在运行时成功,因为它实际上并没有发生,从而留下了可以击败编译时检查的异常系统的方法。
nonSneakyThrow
不会编译,因为该方法的T
下限为Exception
(即T
必须是Exception
或Exception
它本身的超类型),这是一个已检查的异常,这是由于调用该方法的类型而导致的,因此T
推断为Exception
。
在这个网站上为另一个答案编写代码时,我遇到了这样一个特点: 首先,我很困惑为什么调用对编译器来说是可以的。当没有提到任何未检查的异常类型时,它推断出的可能类型是什么? 其次,既然这是可行的,那么编译器为什么要抱怨调用呢?他们看起来很像。
主要内容: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的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。通俗点将就是“类型的变量”。这种类型变量可
本文向大家介绍Java8中对泛型目标类型推断方法的改进,包括了Java8中对泛型目标类型推断方法的改进的使用技巧和注意事项,需要的朋友参考一下 一、简单理解泛型 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。通俗点将就是“类型的变量”。这种类型变量可以用在类、接口和方法的创建中。 理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你
我今天升级了一下... 我现在在v0上。2.11我在这个函数中遇到了一个奇怪的运行时错误: 我在没有任何参数的情况下调用函数,得到了子类型错误。 此代码在DartPad中工作。 有人知道会发生什么吗?