1. 关于java的异常处理,请详细解析
A、C、F
unchecked exception,未检查异常,继承自RuntimeException,不需要显示的捕获,比如空指针异常。通常这种异常是可以避免的,比如通过检验对象是否为空,避免发生NPE。
如果只是想要获取异常的描述信息,可以通过e.getMessage()获取。
如果要获取异常栈信息,则可以通过e.printStackTrace()获取。
2. java.lang.NullPointerException错误,请教高手
楼上在说啥涅?这个不是简单网页的问题咧。。写java估计都是用MyEclipse的吧。呵呵,问题在代码上有一句遗漏了。
首先说一下,这个是空指针异常,估计你不会不知道的,呵呵。
具体问题在你的 rs = stmt.executeQuery(sql)这一行吧。
因为你的sql没有定义语句,所以rs就为NULL,得不到值,你打印的时候就NullPointerException了呗。
而且一般都不建议这样写程序,一般都把增删查改的函数分开来写,写在另外一个专用的工具类里面。语句也是写在函数中,不是在外面写。这样也免了你拼字符串的辛苦。如果有什么问题可以“知道”我,我基本在线的。
回答完毕,给分吧。
3. 试编程:求一个数的绝对值。列如输入-5,则输出5。第1题怎么写
作者 | 沉默王二
来源 | CSDN博客
头图 | 付费下载自视觉中国
出品 | CSDN(ID:CSDNnews)
想学习,永远都不晚,尤其是针对 Java 8 里面的好东西,Optional 就是其中之一,该类提供了一种用于表示可选值而非空引用的类级别解决方案。作为一名 Java 程序员,我真的是烦透了 NullPointerException(NPE),尽管和它熟得就像一位老朋友,知道它也是迫不得已——程序正在使用一个对象却发现这个对象的值为 null,于是 Java 虚拟机就怒发冲冠地把它抛了出来当做替罪羊。
当然了,我们程序员是富有责任心的,不会坐视不管,于是就有了大量的 null 值检查。尽管有时候这种检查完全没有必要,但我们已经习惯了例行公事。终于,Java 8 看不下去了,就引入了 Optional,以便我们编写的代码不再那么刻薄呆板。
没有 Optional 会有什么问题
我们来模拟一个实际的应用场景。小王第一天上班,领导老马就给他安排了一个任务,要他从数据库中根据会员 ID 拉取一个会员的姓名,然后将姓名打印到控制台。虽然是新来的,但这个任务难不倒小王,于是他花了 10 分钟写下了这段代码:
1public class WithoutOptionalDemo {
2 class Member {
3 private String name;
4
5 public String getName() {
6 return name;
7 }
8
9 public void setName(String name) {
10 this.name = name;
11 }
12 }
13
14 public static void main(String[] args) {
15 Member mem = getMemberByIdFromDB();
16 if (mem != null) {
17 System.out.println(mem.getName());
18 }
19 }
20
21 public static Member getMemberByIdFromDB() {
22 // 当前 ID 的会员不存在
23 return null;
24 }
25}
由于当前 ID 的会员不存在,所以 getMemberByIdFromDB() 方法返回了 null 来作为没有获取到该会员的结果,那就意味着在打印会员姓名的时候要先对 mem 判空,否则就会抛出 NPE 异常,不信?让小王把 if (mem != null) 去掉试试,控制台立马打印错误堆栈给你颜色看看。
1Exception in thread "main" java.lang.NullPointerException
2 at com.cmower.dzone.optional.WithoutOptionalDemo.main(WithoutOptionalDemo.java:24)
Optional 是如何解决这个问题的
小王把代码提交后,就兴高采烈地去找老马要新的任务了。本着虚心学习的态度,小王请求老马看一下自己的代码,于是老王就告诉他应该尝试一下 Optional,可以避免没有必要的 null 值检查。现在,让我们来看看小王是如何通过 Optional 来解决上述问题的。
1public class OptionalDemo {
2 public static void main(String[] args) {
3 Optional optional = getMemberByIdFromDB();
4 optional.ifPresent(mem -> {
5 System.out.println("会员姓名是:" + mem.getName());
6 });
7 }
8
9 public static Optional getMemberByIdFromDB() {
10 boolean hasName = true;
11 if (hasName) {
12 return Optional.of(new Member("沉默王二"));
13 }
14 return Optional.empty();
15 }
16}
17class Member {
18 private String name;
19
20 public String getName() {
21 return name;
22 }
23
24 // getter / setter
25}
getMemberByIdFromDB() 方法返回了 Optional 作为结果,这样就表明 Member 可能存在,也可能不存在,这时候就可以在 Optional 的 ifPresent() 方法中使用 Lambda 表达式来直接打印结果。
Optional 之所以可以解决 NPE 的问题,是因为它明确的告诉我们,不需要对它进行判空。它就好像十字路口的路标,明确地告诉你该往哪走。
创建 Optional 对象
1)可以使用静态方法 empty() 创建一个空的 Optional 对象
1Optional empty = Optional.empty();
2System.out.println(empty); // 输出:Optional.empty
2)可以使用静态方法 of() 创建一个非空的 Optional 对象
1Optional opt = Optional.of("沉默王二");
2System.out.println(opt); // 输出:Optional[沉默王二]
当然了,传递给 of() 方法的参数必须是非空的,也就是说不能为 null,否则仍然会抛出 NullPointerException。
1String name = null;
2Optional optnull = Optional.of(name);
3)可以使用静态方法 ofNullable() 创建一个即可空又可非空的 Optional 对象
1String name = null;
2Optional optOrNull = Optional.ofNullable(name);
3System.out.println(optOrNull); // 输出:Optional.empty
ofNullable() 方法内部有一个三元表达式,如果为参数为 null,则返回私有常量 EMPTY;否则使用 new 关键字创建了一个新的 Optional 对象——不会再抛出 NPE 异常了。
判断值是否存在
可以通过方法 isPresent() 判断一个 Optional 对象是否存在,如果存在,该方法返回 true,否则返回 false——取代了 obj != null 的判断。
1Optional opt = Optional.of("沉默王二");
2System.out.println(opt.isPresent()); // 输出:true
3
4Optional optOrNull = Optional.ofNullable(null);
5System.out.println(opt.isPresent()); // 输出:false
Java 11 后还可以通过方法 isEmpty() 判断与 isPresent() 相反的结果。
1Optional opt = Optional.of("沉默王二");
2System.out.println(opt.isPresent()); // 输出:false
3
4Optional optOrNull = Optional.ofNullable(null);
5System.out.println(opt.isPresent()); // 输出:true
非空表达式
Optional 类有一个非常现代化的方法——ifPresent(),允许我们使用函数式编程的方式执行一些代码,因此,我把它称为非空表达式。如果没有该方法的话,我们通常需要先通过 isPresent() 方法对 Optional 对象进行判空后再执行相应的代码:
1Optional optOrNull = Optional.ofNullable(null);
2if (optOrNull.isPresent()) {
3 System.out.println(optOrNull.get().length());
4}
有了 ifPresent() 之后,情况就完全不同了,可以直接将 Lambda 表达式传递给该方法,代码更加简洁,更加直观。
1Optional opt = Optional.of("沉默王二");
2opt.ifPresent(str -> System.out.println(str.length()));
Java 9 后还可以通过方法 ifPresentOrElse(action, emptyAction) 执行两种结果,非空时执行 action,空时执行 emptyAction。
1Optional opt = Optional.of("沉默王二");
2opt.ifPresentOrElse(str -> System.out.println(str.length()), () -> System.out.println("为空"));
设置(获取)默认值
有时候,我们在创建(获取) Optional 对象的时候,需要一个默认值,orElse() 和 orElseGet() 方法就派上用场了。
orElse() 方法用于返回包裹在 Optional 对象中的值,如果该值不为 null,则返回;否则返回默认值。该方法的参数类型和值得类型一致。
1String nullName = null;
2String name = Optional.ofNullable(nullName).orElse("沉默王二");
3System.out.println(name); // 输出:沉默王二
orElseGet() 方法与 orElse() 方法类似,但参数类型不同。如果 Optional 对象中的值为 null,则执行参数中的函数。
1String nullName = null;
2String name = Optional.ofNullable(nullName).orElseGet(()->"沉默王二");
3System.out.println(name); // 输出:沉默王二
从输出结果以及代码的形式上来看,这两个方法极其相似,这不免引起我们的怀疑,Java 类库的设计者有必要这样做吗?
假设现在有这样一个获取默认值的方法,很传统的方式。
1public static String getDefaultValue() {
2 System.out.println("getDefaultValue");
3 return "沉默王二";
4}
然后,通过 orElse() 方法和 orElseGet() 方法分别调用 getDefaultValue() 方法返回默认值。
1public static void main(String[] args) {
2 String name = null;
3 System.out.println("orElse");
4 String name2 = Optional.ofNullable(name).orElse(getDefaultValue());
5
6 System.out.println("orElseGet");
7 String name3 = Optional.ofNullable(name).orElseGet(OrElseOptionalDemo::getDefaultValue);
8}
注:类名 :: 方法名是 Java 8 引入的语法,方法名后面是没有 () 的,表明该方法并不一定会被调用。
输出结果如下所示:
1orElse
2getDefaultValue
3
4orElseGet
5getDefaultValue
输出结果是相似的,没什么太大的不同,这是在 Optional 对象的值为 null 的情况下。假如 Optional 对象的值不为 null 呢?
1public static void main(String[] args) {
2 String name = "沉默王三";
3 System.out.println("orElse");
4 String name2 = Optional.ofNullable(name).orElse(getDefaultValue());
5
6 System.out.println("orElseGet");
7 String name3 = Optional.ofNullable(name).orElseGet(OrElseOptionalDemo::getDefaultValue);
8}
输出结果如下所示:
1orElse
2getDefaultValue
3orElseGet
咦,orElseGet() 没有去调用 getDefaultValue()。哪个方法的性能更佳,你明白了吧?
获取值
直观从语义上来看,get() 方法才是最正宗的获取 Optional 对象值的方法,但很遗憾,该方法是有缺陷的,因为假如 Optional 对象的值为 null,该方法会抛出 NoSuchElementException 异常。这完全与我们使用 Optional 类的初衷相悖。
1public class GetOptionalDemo {
2 public static void main(String[] args) {
3 String name = null;
4 Optional optOrNull = Optional.ofNullable(name);
5 System.out.println(optOrNull.get());
6 }
7}
这段程序在运行时会抛出异常:
1Exception in thread "main" java.util.NoSuchElementException: No value present
2 at java.base/java.util.Optional.get(Optional.java:141)
3 at com.cmower.dzone.optional.GetOptionalDemo.main(GetOptionalDemo.java:9)
尽管抛出的异常是 NoSuchElementException 而不是 NPE,但在我们看来,显然是在“五十步笑百步”。建议 orElseGet() 方法获取 Optional 对象的值。
过滤值
小王通过 Optional 类对之前的代码进行了升级,完成后又兴高采烈地跑去找老马要任务了。老马觉得这小伙子不错,头脑灵活,又干活积极,很值得培养,就又交给了小王一个新的任务:用户注册时对密码的长度进行检查。
小王拿到任务后,乐开了花,因为他刚要学习 Optional 类的 filter() 方法,这就派上了用场。
1public class FilterOptionalDemo {
2 public static void main(String[] args) {
3 String password = "12345";
4 Optional opt = Optional.ofNullable(password);
5 System.out.println(opt.filter(pwd -> pwd.length() > 6).isPresent());
6 }
7}
filter() 方法的参数类型为 Predicate(Java 8 新增的一个函数式接口),也就是说可以将一个 Lambda 表达式传递给该方法作为条件,如果表达式的结果为 false,则返回一个 EMPTY 的 Optional 对象,否则返回过滤后的 Optional 对象。
在上例中,由于 password 的长度为 5 ,所以程序输出的结果为 false。假设密码的长度要求在 6 到 10 位之间,那么还可以再追加一个条件。来看小王增加难度后的代码。
1Predicate len6 = pwd -> pwd.length() > 6;
2Predicate len10 = pwd -> pwd.length() < 10;
3
4password = "1234567";
5opt = Optional.ofNullable(password);
6boolean result = opt.filter(len6.and(len10)).isPresent();
7System.out.println(result);
这次程序输出的结果为 true,因为密码变成了 7 位,在 6 到 10 位之间。想象一下,假如小王使用 if-else 来完成这个任务,代码该有多冗长。
转换值
小王检查完了密码的长度,仍然觉得不够尽兴,觉得要对密码的强度也进行检查,比如说密码不能是“password”,这样的密码太弱了。于是他又开始研究起了 map() 方法,该方法可以按照一定的规则将原有 Optional 对象转换为一个新的 Optional 对象,原有的 Optional 对象不会更改。
先来看小王写的一个简单的例子:
1public class OptionalMapDemo {
2 public static void main(String[] args) {
3 String name = "沉默王二";
4 Optional nameOptional = Optional.of(name);
5 Optional intOpt = nameOptional
6 .map(String::length);
7
8 System.out.println( intOpt.orElse(0));
9 }
10}
在上面这个例子中,map() 方法的参数 String::length,意味着要 将原有的字符串类型的 Optional 按照字符串长度重新生成一个新的 Optional 对象,类型为 Integer。
搞清楚了 map() 方法的基本用法后,小王决定把 map() 方法与 filter() 方法结合起来用,前者用于将密码转化为小写,后者用于判断长度以及是否是“password”。
1public class OptionalMapFilterDemo {
2 public static void main(String[] args) {
3 String password = "password";
4 Optional opt = Optional.ofNullable(password);
5
6 Predicate len6 = pwd -> pwd.length() > 6;
7 Predicate len10 = pwd -> pwd.length() < 10;
8 Predicate eq = pwd -> pwd.equals("password");
9
10 boolean result = opt.map(String::toLowerCase).filter(len6.and(len10 ).and(eq)).isPresent();
11 System.out.println(result);
12 }
13}
好了,我亲爱的读者朋友,以上就是本文的全部内容了——可以说是史上最佳 Optional 指南了,能看到这里的都是最优秀的程序员,二哥必须要伸出大拇指为你点个赞。
https://blog.csdn.net/qing_gee/article/details/104767082
4. java用ireport 打印报表,求助大神
将需要批量打印的内容生成的结果集传递给报表模板就可以了,会自动批量打印。
不预览循环批量打印要怎样实现?
需要调用打印接口 JasperPrintManager类可以直接实现打印。具体资料你可以参考Api
我用的是printReport 方法。
主要就是先在服务器端生成JasperPrint对象,返回给客户端。
下面代码网络到的,你可以参考。
import java.io.File;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.lowagie.text.ExceptionConverter;
import com.sofn.struts.dto.UserInfoDTO;
import com.sofn.struts.op.UserInfo;
import com.sofn.util.UserSessionOperate;
public class ReportViewAction extends Action {
(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
public ActionForward execute(ActionMapping mapping,ActionForm form, HttpServletRequest request,HttpServletResponse response)
throws Exception {
//已编译文件路径和格式
String fp =this.getServlet().getServletContext().getRealPath("/")+ "report\\jasper\\"+ request.getAttribute("rdoc")+ ".jasper";
File reportFile = new File(fp);
// System.out.println("报表路径!!!!!!!"+reportFile);
Map parameters = (Map) request.getAttribute("paras");
byte[] bytes = null;
List list = new ArrayList();
DataSource ds = null;
JasperPrint jasperPrint=null;
//参数传递
UserSessionOperate uso = new UserSessionOperate();
String user = uso.getUser(request);
UserInfo eidr = new UserInfo();
UserInfoDTO eidrdto = null;
String deptname = "物流部门";
String username = "陈云刚";
parameters.put("marker", username);
parameters.put("bumen", deptname);
//数据库连接
try {
String source = "java:comp/env/jdbc/posuse";
Context ic = null;
if (ic == null)
ic = new InitialContext();
ds = (DataSource) ic.lookup(source);
if (ds == null) {
System.out.println("Reportview----22222!");
}
} catch (NameNotFoundException nfe) {
nfe.toString());
} catch (Exception ne) {
ne.printStackTrace();
}
//使用数据源
if (request.getAttribute("datasource") != null) {
list = (List) request.getAttribute("reportlist");
JRBeanCollectionDataSource jds =new JRBeanCollectionDataSource(list); //使用数据源
}
//使用SQL查询
try {
jasperPrint =JasperFillManager.fillReport(reportFile.getPath(),parameters,ds.getConnection());//填充报表数据生成JasperPrint对象
JasperPrintManager.printReport(jasperPrint, false);//2008-08-25 直接打印,不用预览PDF直接打印 true为弹出打印机选择.false为直接打印.
} catch (JRException jre) {
//System.out.println("Reportview----JRException88888");
jre.printStackTrace();
} catch (ExceptionConverter ec) {
ec.getLocalizedMessage());
ec.printStackTrace();
} catch (NullPointerException npe) {
npe.getLocalizedMessage());
npe.getMessage());
npe.toString());
System.err);
} catch (Exception ee) {
ee.printStackTrace();
}
//输出
response.setContentType("application/octet-stream");
ServletOutputStream ouputStream = response.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(ouputStream);
oos.writeObject(jasperPrint);//将JasperPrint对象写入对象输出流中
oos.flush();
oos.close();
ouputStream.flush();
ouputStream.close();
return mapping.findForward("view"); //转向
}
}
5. 昆明电脑培训学校告诉你程序员需要掌握哪些开发框架和语言
一般情况下,java编程开发程序员都掌握了许多的编程开发工具和框架来辅助项目工作。今天我们就一起来了解一下,对于java程序员来说有哪些好用的编程框架语言。
Kotlin是JVM上比较新的语言之一,来自IntelliJ开发商JetBrains。它是一种静态类型语言,旨在提供一种混合OO和FP的编程风格。Kotlin编译器生成的字节码与JVM兼容,可以在JVM上运行及与现有的库互操作。2017年,谷歌支持将其用于Android开发,Kotlin获得了重大突破。
JetBrains有一个明确的目标:让Kotlin成为一种多平台语言,并提供Java互操作性。Kotlin近的成功和成熟水平为它进入服务器端提供了一个很好的机会。
选择Kotlin的理由
许多语言都试图成为更好的Java。Kotlin在语言和生态系统方面做得都很好。成为更好的Java,同时又要保护JVM和巨大的库空间,这是一场姗姗来迟的进化。这种方法与来自JetBrains和谷歌的支持相结合,使它成为一个真正的竞争者。让我们来看看Kotlin带来的一些特性。
类型推断——类型推断是一等特性。Kotlin推断变量的类型,而不需要显式指定。在需要明确类型的情况下,也可以指定类型。
通过引入var关键字,Java10也在朝着类似的方向发展。虽然表面看起来类似,但它的范围仅限于局部变量,不能用于字段和方法签名。
严格空检查——Kotlin将可空代码流视为编译时错误。它提供了额外的语法来处理空检查。值得注意的是,它提供了链式调用中的NPE保护。
与Java互操作——Kotlin在这方面明显优于其他JVM语言。它可以与Java无缝地交互。可以在Kotlin中导入框架中的Java类并使用,反之亦然。值得注意的是,Kotlin集合可以与Java集合互操作。
不变性——Kotlin鼓励使用不可变的数据结构。常用的数据结构(Set/List/Map)是不可变的,除非显式地声明为可变的。变量也被指定为不可变(val)和可变(var)。昆明北大青鸟http://www.kmbdqn.cn/发现所有这些变化对状态可管理性的影响是显而易见的。
简洁而富有表达力的语法——Kotlin引入了许多改进,这些改进对代码的可读性产生了重大影响。
6. 如何更好地使用Java 8的Optional
Java 8中的Optional<T>是一个可以包含或不可以包含非空值的容器对象,在 Stream API中很多地方也都使用到了Optional。
java中非常讨厌的一点就是nullpoint,碰到空指针就会出错抛Exception,然后需要逐行检查是哪个对象为空,带来大量的不必要精力损耗,抛出NPE错误不是用户操作的错误,而是开发人员的错误,应该被避免,那么只能在每个方法中加入非空检查,阅读性和维护性都比较差。
如下面这个代码的手工非空检查:
public void addAddressToCustomer(Customer customer, Address newAddress){ if ( customer == null || newAddress == null) return; if ( customer.getAddresses() == null ){ customer.setAddresses ( new ArrayList<>()); } customer.addAddress(newAddress);}
另外还有一些开发人员喜欢通过非空检查来实现业务逻辑,空对象不应该用来决定系统的行为,它们是意外的Exceptional值,应当被看成是错误,而不是业务逻辑状态。
当我们一个方法返回List集合时,应该总是返回一个空的List,而不是Null,这就允许调用者能够遍历它而不必检查Null,否则就抛出NPE。
但是如果我们根据标识键ID查询数据库,没有查到,需要返回一个空对象怎么办?有人建议抛出Exception,其实这不符合函数方法一进一出的原则,变成一个函数方法有两个返回,一个是正常返回,一个出错Exception,函数式编程范式告诫我们不要轻易抛Exception。
这时Java 8的Optional就发挥作用了,允许我们返回一个空的对象。
Optional<T>有方法 isPresent() 和 get() 是用来检查其包含的对象是否为空或不是,然后返回它,如:
Optional<SomeType> someValue = someMethod();
if (someValue.isPresent()) { // check
someValue.get().someOtherMethod(); // retrieve and call
}
但是这种用法并不能体现Java 8的全部好处,你可以将Optional看成是需要使用某个T值的方法之间某种中间人或者协调者Mediator,而不只是一个普通对象的包装器。
如果你有一个值返回类型T,你有一个方法需要使用这个值,那么你可以让 Optional<T> 处于中间,确保它们之间交互进行,而不必要人工干预。
这样,协调者Optional<T>能够照顾T的值提供给你的方法作为输入参数,在这种情况下,如果T是空,可以确保不会出错,这样在T值为空时也可以让一切都正常运作,你也可以让Optional<T>执行其他动作,如执行一段代码块等等,这样它就实际上是语言机制的很好的补充。
下面这个案例涉及到Lambda表达式 方法引用,是将单词流中第一个以"L"开始单词取出,作为返回结果是一个Optional<String>。
7. Java的异常中什么是”被检查的异常“,什么是”不被检查的异常“被检查是怎样检查的
Java中异常分为2种情况One:已检查异常(编译异常)Two:未检查异常(RunIng异常)检查时异常指的是在编译期间Java的编译器对代码的一种检测比如 int i;System.out.println(i+2);在编译期就过不去,Java对变量的使用必须初始化为检查异常就比较多了数组越界,类型转换错误,空指针........在程序跑起来之后才晓得
8. 如何更好地使用Java 8的Optional
Java8中的Optional是一个可以包含或不可以包含非空值的容器对象,在StreamAPI中很多地方也都使用到了Optional。java中非常讨厌的一点就是nullpoint,碰到空指针就会出错抛Exception,然后需要逐行检查是哪个对象为空,带来大量的不必要精力损耗,抛出NPE错误不是用户操作的错误,而是开发人员的错误,应该被避免,那么只能在每个方法中加入非空检查,阅读性和维护性都比较差。如下面这个代码的手工非空检查:(Customercustomer,AddressnewAddress){if(customer==null||newAddress==null)return;if(customer.getAddresses()==null){customer.setAddresses(newArrayList());}customer.addAddress(newAddress);}另外还有一些开发人员喜欢通过非空检查来实现业务逻辑,空对象不应该用来决定系统的行为,它们是意外的Exceptional值,应当被看成是错误,而不是业务逻辑状态。当我们一个方法返回List集合时,应该总是返回一个空的List,而不是Null,这就允许调用者能够遍历它而不必检查Null,否则就抛出NPE。但是如果我们根据标识键ID查询数据库,没有查到,需要返回一个空对象怎么?有人建议抛出Exception,其实这不符合函数方法一进一出的原则,变成一个函数方法有两个返回,一个是正常返回,一个出错Exception,函数式编程范式告诫我们不要轻易抛Exception。这时Java8的Optional就发挥作用了,允许我们返回一个空的对象。Optional有方法isPresent()和get()是用来检查其包含的对象是否为空或不是,然后返回它,如:OptionalsomeValue=someMethod();if(someValue.isPresent()){//checksomeValue.get().someOtherMethod();//retrieveandcall}但是这种用法并不能体现Java8的全部好处,你可以将Optional看成是需要使用某个T值的方法之间某种中间人或者协调者Mediator,而不只是一个普通对象的包装器。如果你有一个值返回类型T,你有一个方法需要使用这个值,那么你可以让Optional处于中间,确保它们之间交互进行,而不必要人工干预。这样,协调者Optional能够照顾T的值提供给你的方法作为输入参数,在这种情况下,如果T是空,可以确保不会出错,这样在T值为空时也可以让一切都正常运作,你也可以让Optional执行其他动作,如执行一段代码块等等,这样它就实际上是语言机制的很好的补充。下面这个案例涉及到Lambda表达式方法引用,是将单词流中第一个以"L"开始单词取出,作为返回结果是一个Optional。