从lambda表达式中抛出异常

lambda表达式可以抛出异常,但是,如果抛出经检查的异常(checked exception),该异常就必须与函数式接口的抽象方法的throws子句中列出的异常兼容.例如,如果lambda表达式抛出IOException,那么函数式接口中的抽象方法必须列出throws子句中的IOException,下面的程序演示了这个事实:
public class test2
{
    public static void main(String args[])
    {
     double[] values = {1.0,2.0,3.0,4.0,5.0};
     
     MyIoAction myIO = (rdr)->{
         int ch = rdr.read(); //could throw  IOExceptoin
         return true;
     };
    }
}
interface MyIoAction
{
    boolean ioActin(Reader rdr) throws  IOException;
}
因为调用read()方法可能会导致抛出IOException,所以函数式接口MyIoAction的ioAction()方法必须包含Throws子句中的IOException.如果不这样做,程序将无法通过编译,因为lambda表达式将不再与ioAction()兼容,为了证实这一点,只需移除throws子句并试着编译程序,如你所见,这将会导致错误.
问:lambda表达式可以使用数组做为形参吗?
答:可以,然而,当推断形参类型时,lambda表达式的形参并不是使用标准的数组语法指定的.相反,可以将形参指定为简单的名称,如指定为n,而不是n[].记住,lambda表达式的形参类型将从目标上下文推断得出.因为,如果目标上下文需要数组,则形参的类型将自动被推断为数组.为了更好的理解这一点,喜爱按介绍一个小的示例:
如下是一个名为MyTransform的泛型函数式接口,用于将一些转换应用于数组元素:
interface MyTransform
{
    void transform(T[] a);
}
注意:transform()方法的形参是类型为T的数组,现在考虑如下lambda表达式,该表达式使用MyTransform将double数组元素转换为他们的平方根:
MyTransform<Double> sqrts = (v)->{
    for(int i=0;i<v.length;i++) v[i] = Math.sqrt(v[i]);
}
在这里,transform()中a的类型为Double[],因为当声明sqrts时将double指定成了MyTransform的形参类型.所以lambda表达式中的v的类型被推断为double[].没有必要指定v[]
最后要指出的一点是,将lambda形参声明为double[] v也是合法的,因为将形参显式的声明为Double[] v是合法的,但是在本例中这么做不会有什么好处.