会java的鸭子_鸭子在Java中打字? 好吧,不完全是

会java的鸭子

根据维基百科,鸭子的打字是:

动态类型的类型,其中对象的方法和属性确定有效的语义,而不是其从特定类或特定接口的实现继承

用简单的话

当我看到一只鸟走路像鸭子,游泳像鸭子,嘎嘎像鸭子一样时,我称那只鸟为鸭子

在具有动态类型的语言中,此功能允许创建的功能不检查传递的对象的类型,而是依赖于其中存在的特定方法/属性,并在找不到这些属性时抛出运行时异常。 例如,在groovy中,我们可以使用一种方法来打印有关某个实体的信息

def printEntity = {entity ->println 'id: ${entity.id}, name: ${entity.name}' 
}

假设我们有以下课程

class Entity {Long idString name
}

这样我们就可以调用我们的函数

printEntity(new Entity(id: 10L, name: 'MyName1'))
id: 10, name: MyName1

但同时我们可以将map作为参数传递

printEntity(['id':10L, 'name':'MyName2'])
id: 10, name: MyName2

使用一些元编程魔术,我们甚至可以编写以下内容

class Ghost {def propertyMissing(String name) {if (name == 'id') {return -1L} else if (name == 'name') {return 'StubName'}}
}

而且我们仍然可以调用我们的函数

printEntity(new Ghost())
id: -1, name: StubName

欢迎来到真实的世界

幸运的是,这个概念不仅可以用于具有动态类型的语言,而且可以用于具有更严格类型模型的语言(例如Java)。 Wikipedia很好地说明了使用Proxy类在Java中进行鸭子输入的实现。

好吧,你说,除了让自己成为最聪明的专家以外,这的实际用途是什么:)让我展示一些使用鸭子类型技术在Java中解决的现实生活任务。

从一开始,我就有一个简单的报表生成器,用于查询产品数据库,并输出某些实体的ID和名称。 但随后客户说:“我也想链接到我们网站上的实体详细信息页面。 美丽的SEO友好链接。 你能对我这样做吗? 我说。 深入研究我们的代码库后,我发现很酷的函数generateSeoUrl()可以完成这项工作。 该函数采用Entity类型的一个参数,即interface。 因此,我的目的是观察Entity的实现,并尝试使用其中之一进行报告生成。 当我发现它们都属于某些自制的ORM工具并且其构造函数接受查询DB以获取有关产品的全部信息后,我感到非常惊讶。

因此,如果使用的是实体实现,则必须在报表的每一行中处理一个额外的查询,这是不可接受的,因为报表由大量的行组成。 因此,我决定尝试其他方法并实现Entity接口,该方法覆盖了generateSeoUrl()使用的方法。 我单击我的IDE快捷方式,再次感到惊讶。 实体有大约50(!!!)个方法。 好吧,我已经知道generateSeoUrl()函数只使用getEntityId()和getName(),但是再说一次,使用具有50个空方法的新类来覆盖其中的2个做有用的动作对我来说不是一个好主意。

因此,我决定停止尝试编码,并开始考虑:)扩展某些Entity实现以防止查询数据库或复制+粘贴generateSeoUrl()并根据我的需要采用它,但是这些选择仍然很漂亮。 特别是当我提醒鸭子打字时。 我对自己说,我们有一个采用Entity实例但仅使用此接口的两种方法的函数,因此要完成我的任务,我需要看起来像Entity并能够处理getEntityId()和getName()方法的东西。

由于EntityId和name已经存在于用于生成报告的数据中,因此我可以在新类中重用它们以对getEntityId()和getName()的数据进行存根。 为了实现鸭子类型,我们需要创建Proxy,该Proxy也实现InvocationHandler接口和静态方法来检索Proxy的实例。 我班的最终代码看起来像

public class ReportEntitySupport implements InvocationHandler {public static Entity newInstance(Long entityId, String name) {return (Entity) Proxy.newProxyInstance(Product.class.getClassLoader(),Product.class.getInterfaces(),new ReportEntitySupport(entityId, name));}private final String name;private final Long entityId;private ReportEntitySupport(Long entityId, String name) {this.name = name;this.entityId = entityId;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals('getName')) {return this.name;} else if (method.getName().equals('getEntityId')) {return this.entityId;}return null;}
}

那么如何使用呢?

在我的报表生成器类中,同时遍历ResultSet时,我正在使用以下代码

Long entityId;
String name;
....
Entity entity = ReportEntitySupport.newIntance(entityId, name);
String seoUrl = generateSeoUrl(entity);
....

聚苯乙烯

这篇文章仅说明了一些不常见的Java语言概念可以成功地用于完成现实生活中的任务,从而提高您的编程技能并使代码更漂亮。

参考: 鸭子在Java中打字? 嗯,并非完全来自我们JCG合作伙伴 Evgeny Shepelyuk在jk的博客博客中。


翻译自: https://www.javacodegeeks.com/2012/09/duck-typing-in-java-well-not-exactly.html

会java的鸭子

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

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

相关文章

数据结构(六)查找---多路查找树(2-3-4树)

一:2-3-4树 具体操作同2-3树 2-3-4树是2-3树的扩展,包括了4节点的使用,一个4节点包含小中大三个元素和四个孩子(或没有孩子)。 (一)插入实现 构建一个数组为{7,1,2,5,6,9,8,4,3}的2-3-4树的过程…

java web 静态_「Java Web」主页静态化的实现

一个站点的主页一般不会频繁变动,而大多数用户在訪问站点时不过浏览一下主页(未登陆)。然后就离开了。对于这类訪问请求。假设每次都要通过查询数据库来显示主页的话,显然会给server带来多余的压力。这时候我们能够将主页静态化。在减轻数据库server压力…

实现Java监视的12个步骤程序存在缺陷

Java监视的当前状态最大的问题是什么? 生产中的错误很像喝醉的短信。 您只有在事情已经发生之后才意识到出了点问题。 发短信日志通常比应用程序错误日志更有趣,但是……两者都同样难以修复。 在本文中,我们将执行一个12步的监视漏洞修复程…

创建django项目

1.新建django项目 打开命令行,进入想要安置项目的目录,命令行输入:django-admin startproject my_web 用Pycharm打开 2.开启服务器 命令行进入my_web目录。输入:python manage.py runserve开启服务器, 将服务器的地址复…

有关fwrite语句的用法

一:函数名: fwrite 功 能: 写内容到流中 用 法:fwrite(buffer,size,count,fp); (1)buffer:是一个指针,对fwrite来说,是要输出数据的地址。 (2)size:要写入的字节数&#…

json 全文索引 mysql_MySQL全文索引、联合索引、like查询、json查询速度大比拼

查询背景有一个表tmp_test_course大概有10万条记录,然后有个json字段叫outline,存了一对多关系(保存了多个编码,例如jy1577683381775)我们需要在这10万条数据中检索特定类型的数据,目标总数据量:条2931SELECT COUNT(*)…

java从端口获取数据库_Java之通过接口获取数据并用JDBC存储到数据库中

最近做数据同步功能,从接口获取数据然后存到数据库中以便后续对数据进行相关操作,下面就贴一下相关代码。1 import com.alibaba.fastjson.JSON;2 import com.alibaba.fastjson.JSONObject;34 public class Digests {5 private static final String APPKE…

支付宝H5 与网页端支付开发

在日常生活中,我们基本上都是进行微信与支付宝的支付方式尽心支付,这种方式确实大大便利了我们的生活,那么如何在我们的产品中进行微信与支付宝支付的植入开发呢? 我们先进行支付宝的H5与网页端支付开发,这里只进行支付…

C/C++中extern关键字详解

1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。 也就是说extern有两个作用,第一个,当它与"C"…

javaone_JavaOne 2012:NetBeans.Next –未来路线图

javaone我从Continental Ballroom 4和一个NetBeans主题( Easel项目 )到Continental Ballroom 5,走了必要的几个步骤,以查看另一个面向NetBeans的演示文稿:“ NetBeans.Next –未来路线图”。 Ashwin Rao着手介绍羽毛之…

java简单编译器源代码_25行代码实现一个简单的编译器

起因《25行JavaScript语句实现一个简单的编译器》实现的是一个简单到不能再简单的玩具的玩具,他的魔法是函数式编程简化了js代码。java 8提供了函数式编程的支持,昨晚脑子抽风突然兴趣java也可以实现一个如此简单的编译器!java和js语言差异ja…

《python网络数据采集》读后感 第六章:读取文档

1.文档编码: 文档编码是一种告诉程序——无论是计算机的操作系统还是 Python 代码——读取文档的规 则。文档编码的方式通常可以根据文件的扩展名进行判断,虽然文件扩展名并不是由编码 确定的,而是由开发者确定的。例如,如果我把 …

如何在Gradle多项目构建中管理依赖项

从很早以前我就一直喜欢Gradle构建工具。 它的潜力甚至在1.0版本之前就已经很明显了,那时变化经常被打破。 如今,升级很少会引起意外。 该工具已经成熟并且运行良好。 Gradle包括一个功能强大的依赖项管理系统,该系统可以与Maven和Ivy存储库…

Linux下nm和ldd 命令

1. Linux nm 命令 nm [‘-a’|‘--debug-syms’] [‘-g’|‘--extern-only’] [‘-B’] [‘-C’|‘--demangle’[style]] [‘-D’|‘--dynamic’] [‘-S’|‘--print-size’] [‘-s’|‘--print-armap’] [‘-A’|‘-o’|‘--print-file-name’][‘--special-syms’] [‘-n’|‘…

mysql alter table_mysql ALTER TABLE 的用法

在表格被建立在资料库中后,我们常常会发现,这个表格的结构需要有所改变。常见的改变如下:加一个栏位删去一个栏位改变栏位名称改变栏位的资料种类以上列出的改变并不是所有可能的改变。ALTER TABLE 也可以被用来作其他的改变,例如…

WEB开发技术点

做为一个WEb类MIS的开发者,涉及的知识点很多,总结成图,方便自已学习 转载于:https://www.cnblogs.com/ezezwyj/p/9515859.html

mysql8中怎么增删一列_MYSQL 第八课 数据的增删改

#DML语言/*数据操作语言:插入:insert修改:update删除:delete*/#一、插入语句#方式一:经典的插入/*语法:insert into 表名(列名,...) values(值1,...);*/SELECT * FROM beauty;#1.插入的值的类型要与列的类型…

c++中new和delete的使用方法

new和delete运算符用于动态分配和撤销内存的运算符 new用法: 1. 开辟单变量地址空间 1)new int; //开辟一个存放数组的存储空间,返回一个指向该存储空间的地址.int *a new int 即为将一个int类型的地址赋值给整型指针a. 2)int *a new int(5) 作用同上,但是同时将整数赋…

学习笔记--Dubbo

Dubbo学习笔记 Dubbo是什么 Dubbo是: 一款分布式服务框架高性能和透明化的RPC远程服务调用方案SOA服务治理方案ZooKeeper服务注册中心 下载 ZooKeeper ,地址 http://www.apache.org/dyn/closer.cgi/zookeeper 解压,修改zoo_sample.cfg 重命名…

apache hive_通过6个简单的步骤在Windows上运行Apache Hive

apache hive注意 :您需要安装cygwin才能运行本教程,因为Hadoop(Hive所需)需要cygwin才能在Windows上运行。 至少,系统中必须存在Basic,Net(OpenSSH,tcp_wrapper软件包)和…