instanceof运算符_Java 8中的instanceof运算符和访客模式替换

instanceof运算符

我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长。 所以我想出了以下DSL语法:

Object msg = //...whenTypeOf(msg).is(Date.class).    then(date -> println(date.getTime())).is(String.class).  then(str -> println(str.length())).is(Number.class).  then(num -> println(num.intValue())).orElse(obj -> println("Unknown " + obj));

在Java 8中,没有向下转换,简洁的语法,强类型的……完全可以实现的。使用lambda和一些泛型,我创建了一个名为typeof的小型库 ,它比instanceofVisitor模式结合在一起是干净的,易于使用且更健壮的。 优势包括:

  • 没有明确的垂头丧气
  • 避免instanceof
  • 清洁且易于使用
  • 强类型
  • 适用于我们无法控制的类,包括JDK

这个小实用程序是出于Akka和Java API的目的而开发的,目的是限制instanceof运算符的使用,但它更通用。 同样,您可以根据运行时类型返回一些信息:

int result = whenTypeOf(obj).is(String.class).thenReturn(String::length).is(Date.class).thenReturn(d -> (int) d.getTime()).is(Number.class).thenReturn(Number::intValue).is(TimeZone.class).thenReturn(tz -> tz.getRawOffset() / 1000).is(MyType.class).thenReturn(7).get();

该库从上到下检查每个is()子句,如果找到包括父类在内的第一个匹配类,则停止运行,因此is(Number.class)将同时匹配IntegerFloat 。 如果没有条件匹配,则调用get将失败,并带有异常。 您可以使用orElse()重写此行为orElse()比等效的is(Object.class)更容易阅读):

int result = whenTypeOf(obj).is(String.class).thenReturn(String::length).//...orElse(42);

DSL利用Java中的静态类型的优势,几乎不可能错误地使用该库-大多数错误会在编译期间立即被发现。 以下所有代码段甚至都不会编译:

//ERROR - two subsequent is()
whenTypeOf(obj).is(Foo.class).is(Bar.class)//ERROR - then() without prior is()
whenTypeOf(obj).then(x -> println(x))//ERROR - mixing then() and thenReturn()
whenTypeOf(obj).is(Foo.class).then(foo -> println(foo)).is(Bar.class).thenReturn(bar -> bar.getB());

基本上,您首先输入whenTypeOf()Ctrl + space会告诉您所允许的内容。 以静态类型语言设计类型安全且健壮的DSL的关键是尽可能地限制API,以便在编译时避免无效的状态和调用。 您最终将获得大量的小类 ,但这没关系,您的用户将看不到这一点。 例如,签出FirstIs.java –第一次调用is()之后返回的对象:

public class FirstIs<S, T> {final Then<S> parent;private final S object;private final Class<T> expectedType;public Then<S> then(Consumer<T> thenBlock) {if (matchingType()) {thenBlock.accept(castObject());return new TerminalThen<>();}return parent;}public <R> ThenReturn<S, R> thenReturn(Function<T, R> result) {if (matchingType()) {return new TerminalThenReturn<>(object, result.apply(castObject()));}return new ThenReturn<>(object);}public <R> ThenReturn<S, R> thenReturn(R result) {if (matchingType()) {return new TerminalThenReturn<>(object, result);}return new ThenReturn<>(object);}//...}

编写DSL比使用DSL困难得多,但最终还是很有收获的。 注意如何使用不同的返回类型( Then vs. ThenReturn )只是为了确保在每个阶段只能访问有效的方法。 一种替代方法是执行运行时检查(例如,您不编写is(...).is(...).then(...) )–但是,如果编译器可以为我们做这件事,为什么还要麻烦?

希望您喜欢本文,如果您愿意在项目中尝试使用此实用程序,请告诉我。 它在GitHub上可用 。

参考:来自Java和社区博客的JCG合作伙伴 Tomasz Nurkiewicz提供的Java 8中的instanceof运算符和访客模式替换 。

翻译自: https://www.javacodegeeks.com/2013/10/instanceof-operator-and-visitor-pattern-replacement-in-java-8.html

instanceof运算符

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python垃圾处理_利用python程序帮大家清理windows垃圾

前言大家应该都有所体会&#xff0c;在windows系统使用久了就会产生一些“垃圾”文件。这些文件有的是程序的临时文件&#xff0c;有的是操作记录或日志等。垃圾随着时间越积越多&#xff0c;导致可用空间减少&#xff0c;文件碎片过多&#xff0c;使得系统的运行速度受到一定影…

基于java家教管理系统_基于jsp的家教信息管理-JavaEE实现家教信息管理 - java项目源码...

基于jspservletpojomysql实现一个javaee/javaweb的家教信息管理, 该项目可用各类java课程设计大作业中, 家教信息管理的系统架构分为前后台两部分, 最终实现在线上进行家教信息管理各项功能,实现了诸如用户管理, 登录注册, 权限管理等功能, 并实现对各类家教信息管理相关的实体…

如何从云功能调用外部REST API

在之前的博客文章中&#xff0c;我展示了如何创建您的第一个云功能 &#xff08;以及一个视频 &#xff09;。 您的云函数很可能需要调用外部REST API。 以下教程将向您展示如何创建此类功能&#xff08;非常简单&#xff09;。 登录到IBM Cloud帐户 点击目录 删除标签&…

sinx泰勒展开_高考中怎么用泰勒公式?

好久没有更新了&#xff0c;最近一直在准备天津市高数竞赛&#xff0c;今天才有空写高考的文章看&#xff0c;并且运用这篇文章的前提要求是已经掌握了绝大多数的高考题型然后了解泰勒拓展知识面什么是泰勒公式&#xff1f;你去百度肯定会有一大堆理论给你解释&#xff0c;今天…

java selenium 日志_java - 支持selenium日志_java_酷徒编程知识库

在自動測試中&#xff0c;Chrome創建了大量日誌&#xff0c;System.setProperty("webdriver.chrome.silentOutput","true");ChromeOptions options new ChromeOptions();options.addArguments("--disable-logging","--log-levelOFF",…

机器学习分类算法_机器学习分类算法

人们曾在自身的神经元得到启发&#xff0c;将机器学习中给出的特征输入与权重之积作为输出与阈值作比较&#xff0c;得到0或者1的输出。这就是我们感知器的实现原理感知器在实现过程中的步骤如下&#xff1a;①将权值初始化称为一个很小的向量②迭代训练所有样本&#xff1a;计…

scala 异步调用_非阻塞异步Java 8和Scala的Try / Success / Failure

scala 异步调用受Heinz Kabutz最近的时事通讯以及我在最近的书中研究的Scala的期货的启发&#xff0c;我着手使用Java 8编写了一个示例&#xff0c;该示例如何将工作提交给执行服务并异步地响应其结果&#xff0c;并使用了回调。无需阻止任何线程等待执行服务的结果。 理论认为…

java简单的事务单元_junit 单元测试事务自动回滚(亲测有效)

junit 单元测试事务会自动回滚。通过Rollback(true)注解来实现&#xff0c;默认是true&#xff0c;事务会回滚&#xff0c;可以不写。false时事务不会回滚&#xff0c;数据会写到数据库中。实例&#xff1a;package com.xiaolyuh.service;import java.util.Date;import org.jun…

linux系统如何打开python_手把手教你在Linux系统下使用Python虚拟环境

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤夕阳无限好&#xff0c;只是近黄昏。/1 前言/Hello小伙伴们&#xff0c;你们好&#xff0c;又是日常get新技能的一天&#xff0c;今天&#xff0c;咱们来整一…

Java EE 7中的资源和依赖注入

1.概述 上下文和依赖注入&#xff08;CDI&#xff09;是Java EE的一项功能&#xff0c;可帮助融合Java EE 6和更高版本中包含的平台的Web层和事务层。 从技术角度来看&#xff0c;这意味着CDI提供了依赖项注入框架&#xff0c;并且还管理了依赖项的生命周期。 今天在本教程中&…

java wrap方法_Java WritableCellFormat.setWrap方法代码示例

import jxl.write.WritableCellFormat; //导入方法依赖的package包/类/*** param workSheet to add the help to* param table to fetch metadata from* param startRow to start adding rows at* param helpTextRowNumbers - map to insert row numbers for each help field i…

python创建tcp socket_Python Socket如何建立TCP连接

在 Python 程序中创建 TCP 服务器时&#xff0c;创建通用 TCP 服务器的一般演示代码如下。需要记住的是&#xff0c;这仅是设计服务器的一种方式。一旦熟悉了服务器设计&#xff0c;可以修改下面的代码来操作服务器。ss socket() #创建服务器套接字ss.bind() #绑定套接字与地址…

ubantu java编辑器_Linux Ubuntu中最好的代码编辑器 程序员都这么看吗?

【IT168 应用】Linux Ubuntu 中最好的代码编辑器是哪个 ? 这要看程序员的使用习惯和喜好了&#xff0c;Atom、Brackets、Sublime Text 是最常用的三个&#xff0c;也许程序员们还有更喜欢的。AtomAtom 是流行&#xff0c;而且十分友好的文本编辑器&#xff0c;而且还可以嵌入到…

apache camel_Apache Camel –从头开始开发应用程序(第1部分/第2部分)

apache camel开始之前 前段时间&#xff0c;我写了一篇关于Spring Integration的教程&#xff0c;以演示如何在受现实发票处理系统启发的示例应用程序中使用Spring Integration。 我对此非常满意&#xff0c;因此我决定向您展示如何使用Apache Camel&#xff08;Spring Integra…

python websocket异步高并发_高并发异步uwsgi+web.py+gevent

为什么用web.py&#xff1f;python的web框架有很多&#xff0c;比如webpy、flask、bottle等&#xff0c;但是为什么我们选了webpy呢&#xff1f;想了好久&#xff0c;未果&#xff0c;硬要给解释&#xff0c;我想可能原因有两个&#xff1a;第一个是兄弟项目组用webpy&#xff…

提示:通过URL激活并发送参数

世界上最安全的密码是不存在的密码。 使用完全随机的密钥从等式中删除用户。 公平地说&#xff0c;这有一些缺点&#xff0c;并且密码仍然存在于某个地方&#xff08;在您的电话/电子邮件中&#xff09;&#xff0c;但通常效果很好。 诀窍很简单&#xff0c;如果我们想对用户进…

weblogic创建域后启动不了_摩托车淋雨后启动不了什么原因?如何解决?

图文是工作&#xff0c;视频是生活。大家好&#xff0c;我是 骑士分享 欢迎您的关注&#xff01;摩托车淋雨后启动不了什么原因&#xff1f;如何解决&#xff1f;这种现象对于电喷车型来说发生的几率并不大&#xff0c;原因就在于电喷车型的线路防水能力会更强&#xff0c;供油…

前端开始学java_[Java教程]开启前端学习之路

[Java教程]开启前端学习之路0 2014-06-10 17:00:06前言第一次在博客园写博客&#xff0c;写写自己开启前端学习之路。应该是受邢师兄的影响吧&#xff0c;不得不说邢师兄人很好&#xff0c;学习也很认真&#xff0c;师兄的前端也是自学的&#xff0c;但是学的很好&#xff0c;大…

python 傅里叶_基于python的图像傅里叶处理

import numpy as npimport matplotlib.pyplot as pltx np.linspace(-10, 10, 1000)a np.cos(x)b a np.cos(3 * x)# d np.log(x)c b np.cos(7 * x)d c - np.cos(10 * x)plt.subplot(2, 2, 1)plt.plot(x, a, label‘$cos(x)$‘, color‘green‘, linewidth1)plt.title(&q…

xalan_如何以10倍速加速Apache Xalan的XPath处理器

xalan一段时间以来&#xff0c; Apache Xalan中存在一个令人尴尬的错误&#xff0c;该错误是XALANJ-2540 。 此错误的后果是Xalan每次XPath表达式求值将内部SPI配置文件加载数千次 &#xff0c;可以很容易地进行如下测量&#xff1a; 这个&#xff1a; Element e (Element)do…