亚型多态性应用于元组的危险

Java 8具有lambda和stream,但是没有元组,这真是令人遗憾 。 这就是为什么我们在jOOλ中实现了元组-Java 8缺少的部分 。 元组确实是无聊的值类型容器。 本质上,它们只是这些类型的枚举:

public class Tuple2<T1, T2> {public final T1 v1;public final T2 v2;public Tuple2(T1 v1, T2 v2) {this.v1 = v1;this.v2 = v2;}// [...]
}public class Tuple3<T1, T2, T3> {public final T1 v1;public final T2 v2;public final T3 v3;public Tuple3(T1 v1, T2 v2, T3 v3) {this.v1 = v1;this.v2 = v2;this.v3 = v3;}// [...]
}

编写元组类是一项非常无聊的任务,最好使用源代码生成器来完成。

其他语言和API的元组

jOOλ的当前版本具有0至16度的元组。C#和其他.NET语言的元组类型介于1至8之间。有一个专门针对元组的特殊库,称为Javatuple ,元组在1至10之间。英里,并给元组单独的英文名称:

Unit<A> // (1 element)
Pair<A,B> // (2 elements)
Triplet<A,B,C> // (3 elements)
Quartet<A,B,C,D> // (4 elements)
Quintet<A,B,C,D,E> // (5 elements)
Sextet<A,B,C,D,E,F> // (6 elements)
Septet<A,B,C,D,E,F,G> // (7 elements)
Octet<A,B,C,D,E,F,G,H> // (8 elements)
Ennead<A,B,C,D,E,F,G,H,I> // (9 elements)
Decade<A,B,C,D,E,F,G,H,I,J> // (10 elements)

为什么?

因为当我看到恩纳德时,它真的会敲响那甜蜜的钟声

最后但并非最不重要的一点是,jOOQ还具有一个类似于元组的内置类型org.jooq.Record ,它是Record7<T1, T2, T3, T4, T5, T6, T7>等漂亮子类型的基本类型Record7<T1, T2, T3, T4, T5, T6, T7> 。 jOOQ遵循Scala并定义了最高22级的记录。

定义元组类型层次结构时要当心

正如我们在前面的示例中看到的, Tuple3Tuple2有很多共同的代码。

由于数十年来的对象定向和多态设计反模式对我们所有人都造成了严重的大脑损害,我们可能认为让Tuple3<T1, T2, T3>扩展Tuple2<T1, T2>是一个好主意,因为Tuple3只是在Tuple2的右边添加了一个属性,对吗? 所以…

public class Tuple3<T1, T2, T3> extends Tuple2<T1, T2> {public final T3 v3;public Tuple3(T1 v1, T2 v2, T3 v3) {super(v1, v2);this.v3 = v3;}// [...]
}

事实是:由于种种原因,这是您最糟糕的事情。 首先,是的。 Tuple2Tuple3都是元组,因此它们确实具有一些共同的特征。 将这些功能归为一个普通的超级类型并不是一个坏主意,例如:

public class Tuple2<T1, T2> implements Tuple {// [...]
}

但是学位不是其中之一。 原因如下:

排列

考虑一下您可以形成的所有可能的元组。 如果让元组彼此延伸,那么例如, Tuple5也将与Tuple2分配兼容。 以下将完美地编译:

Tuple2<String, Integer> t2 = tuple("A", 1, 2, 3, "B");

当让Tuple3扩展Tuple2 ,从扩展链中的元组中删除最右边的属性似乎是一个不错的默认选择。

但是在上面的示例中,为什么我不想重新分配(v2, v4)以使结果为(1, 3)或也许是(v1, v3)从而使结果为("A", 2)

当将较高程度的元组“减少”到较低程度的元组时,可能会涉及很多可能的属性。 默认情况下,删除最右边的属性对于所有用例来说都不会足够普遍

类型系统

如果Tuple3扩展了Tuple2 ,则对类型系统的影响将远远大于上述Tuple2 。 例如,签出jOOQ API。 在jOOQ中,您可以放心地假设以下内容 :

// Compiles:
TABLE1.COL1.in(select(TABLE2.COL1).from(TABLE2))// Must not compile:
TABLE1.COL1.in(select(TABLE2.COL1, TABLE2.COL2).from(TABLE2))

第一个IN谓词是正确的。 谓词的左侧只有一列( 而不是行值表达式 )。 这意味着谓词的右侧也必须对单列表达式进行操作,例如,选择单个列(相同类型)的SELECT子查询。

第二个示例选择了太多列,并且jOOQ API将告诉Java编译器这是错误的。

jOOQ通过Field.in(Select)方法保证了这一点,该方法的签名为:

public interface Field<T> {...Condition in(Select<? extends Record1<T>> select);...
}

因此,您可以提供一个产生Record1<T>类型的任何子类型的SELECT语句。

幸运的是, Record2不会扩展Record1

如果现在Record2扩展了Record1Record1似乎是个好主意,那么第二个查询将突然编译:

// This would now compile
TABLE1.COL1.in(select(TABLE2.COL1, TABLE2.COL2).from(TABLE2))

…即使它形成无效的SQL语句。 它将进行编译,因为它将生成Select<Record2<Type1, Type2>>类型,该类型将是Field.in(Select)方法中预期的Select<Record1<Type1>>的子类型。

结论

Tuple2Tuple5类型基本上是不兼容的类型。 在强类型系统中,您一定不要引诱类似类型或相关类型也应该是兼容类型。

类型层次结构是非常面向对象的,从面向对象的角度来看,我的意思是自90年代以来我们仍然遭受着有缺陷和过度设计的面向对象概念。 即使在“企业”中,大多数人也学会了偏重于继承而不是继承 。 对于元组,组合意味着您可以很好地 Tuple5转换为Tuple2 。 但是您不能分配它。

在jOOλ中 ,可以很容易地完成以下转换:

// Produces (1, 3)
Tuple2<String, Integer> t2_4 = tuple("A", 1, 2, 3, "B").map((v1, v2, v3, v4, v5) -> tuple(v2, v4));// Produces ("A", 2)
Tuple2<String, Integer> t1_3 = tuple("A", 1, 2, 3, "B").map((v1, v2, v3, v4, v5) -> tuple(v1, v3));

这个想法是您对不可变值进行操作,并且可以轻松提取这些值的一部分并将其映射/重组为新值。

翻译自: https://www.javacodegeeks.com/2015/10/the-danger-of-subtype-polymorphism-applied-to-tuples.html

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

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

相关文章

广西计算机二级450034考点,广西计算机等级考试报名地点

2010年下半年全国计算机等级考试时间是2010年9月18日至22日&#xff0c;第一天上午考笔试&#xff0c;上机考试从笔试的当天下午开始(一级从上午开始)。2010年下半年全国计算机等级考试报名时间已经开始&#xff01;如果您是在校生&#xff0c;去学校相关报名处报名最方便&…

HBuilder完成webApp入门(3) 关于webview (转)

个人认为WebView是 html5 API的一个非常重要的部分。 WebView 的帮助文档http://www.html5plus.org/doc/zh_cn/webview.html 为什么对WebView的掌握很重要&#xff1f;因为它是一个HTML5 APP的基础。刚刚学习HBuilder的同学一般会将重点放在 mui 组件上。mui 提供了很多默认的方…

ca证书 csr_linux下使用openssl生成 csr crt CA证书

证书文件生成:一.服务器端1.生成服务器端 私钥(key文件);openssl genrsa -des3 -out server.key 1024运行时会提示输入密码,此密码用于加密key文件(参数des3是加密算法,也可以选用其他安全的算法),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令.如果不要口…

佛山市南海技师学校计算机类,佛山南海信息技术学校2021年有哪些专业

即将面临毕业的时候&#xff0c;同学们都要选择学校&#xff0c;都要选择专业就读&#xff0c;至于选择什么&#xff0c;就是一大难题了。学习是重要的事情&#xff0c;选择更是件大事。小编整理了学校的招生专业详情&#xff0c;仅供参考。佛山南海信息技术学校专业名单&#…

java nio拷贝文件_Java 7 – NIO文件革命

java nio拷贝文件Java 7&#xff08;“项目代币”&#xff09;已于去年7月问世。 此版本中的新增功能很有用&#xff0c;例如&#xff0c;尝试资源-从try块中自动处理可关闭的资源&#xff0c;switch语句中的字符串&#xff0c;用于异常的multicatch以及用于处理泛型的<>…

getresource 路径转义_java中的相对路径和绝对路径

(转载)1.基本概念的理解绝对路径&#xff1a;绝对路径就是你的主页上的文件或目录在硬盘上真正的路径&#xff0c;(URL和物理路径)例如&#xff1a;C:\xyz\test.txt 代表了test.txt文件的绝对路径。http://www.sun.com/index.htm也代表了一个URL绝对路径。相对路径&#xff1a;…

创建 floating IP - 每天5分钟玩转 OpenStack(106)

先复习一下前面我们讨论的知识。 当租户网络连接到 Neutron router&#xff0c;通常将 router 作为默认网关。当 router 接收到 instance 的数据包&#xff0c;并将其转发到外网时: 1. router 会修改包的源地址为自己的外网地址&#xff0c;这样确保数据包转发到外网&#xff…

把ipa文件上传到服务器,windows电脑上传ipa到appstore的详细流程

在使用H5混合开发的app打包后&#xff0c;需要将ipa文件上传到appstore进行发布&#xff0c;就需要去苹果开发者中心进行发布。但是在苹果开发者中心无法直接上传ipa文件&#xff0c;它要求我们使用xcode或transport等工具上传ipa文件&#xff0c;但是xcode和transport不能安装…

Java的5个古怪问题

我们有机会尝试了一些最奇怪的Java难题 即使是最有经验的Java开发人员&#xff0c;也会在这篇文章中发现令人困惑的问题。 或至少是有趣的&#xff08;绝对不公平&#xff09;。 在经历了Java Deathmatch冒险之后&#xff0c;我们决定这次发布一系列不同的问题&#xff0c;着重…

js 取得数组下标_数组的介绍及使用

JavaScript 中的数组常用于在单个变量中存储多个值。数组就是一组数据的集合&#xff0c;在内存中表现为一段连续的内存地址(保存在堆内存)。创建数组的目的就是为了保存更多的数据。数组概念和语法概念&#xff1a;数组是一个特殊变量&#xff0c;一次可以容纳多个值。特点&am…

css的一种预处理器 sass

之前觉得关于css什么的没什么&#xff0c;后来让别人给问住了。。。然后就悲催了。。。 sass是一种css的预处理器&#xff0c;是一种函数式的css的编程&#xff1b; 主要还是看官网 http://www.w3cplus.com/sassguide/ 这个是基于Ruby 1.需要安装&#xff1a; 可以直接自己…

服务器系统巡检记录表,服务器月度巡检记录

《服务器月度巡检记录》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《服务器月度巡检记录(2页珍藏版)》请在人人文库网上搜索。1、服务器月度巡检记录 巡检日期&#xff1a; 年 月 日一、物理环境检查检查内容检查结果备注环境温度温度&#xff1a; &#xff1b; 环…

bigdecimal取小数部分_小数精度丢失问题分析和解决

无论在什么业务中&#xff0c;钱?是非常重要的东西&#xff0c;对账的时候一定要对的上&#xff0c;不能这边少一分钱那边多一分钱。对于数值的计算&#xff0c;尤其是小数&#xff0c;floate和double都是禁止使用的。阿里强制要求存放小数时使用 decimal&#xff0c;禁止使用…

转收藏:Git常用命令速查表

一、 Git 常用命令速查 git branch 查看本地所有分支git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支git branch -r 查看远程所有分支git commit -am "init" 提交并且加注释 git remote add origin git192.168.1.119:ndshowgit push origin m…

php curl ajax get请求,PHP的curl的get,post请求-Fun言

GET请求如下&#xff1a;/** param string $url* return mixed*/public function doGet($url){//初始化$ch curl_init();curl_setopt($ch, CURLOPT_URL,$url); // 执行后不直接打印出来curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_HEADE…

java运行库一键修复_在运行时修补Java

java运行库一键修复本文将重点介绍如何解决与第三方库相关的问题 不能被规避 难以排除/绕过/更换 只需不提供错误修正 在这种情况下&#xff0c;解决问题仍然是一项艰巨的任务。 作为这种情况的诱因&#xff0c;请考虑对“哈希索引”数据结构的攻击&#xff0c;例如java.ut…

使用LinkedList模拟一个堆栈或者队列数据结构

使用LinkedList模拟一个堆栈或者队列数据结构。 堆栈&#xff1a;先进后出 如同一个杯子。 队列&#xff1a;先进先出 如同一个水管。 import java.util.LinkedList;public class DuiLie {private LinkedList link;public DuiLie() {link new LinkedList();}public void m…

k40游戏增强版服务器维护中,Redmi K40 游戏增强版发布,第四台 K40 出现了

原标题&#xff1a;Redmi K40 游戏增强版发布&#xff0c;第四台 K40 出现了今晚 Redmi 发布了旗下的新款游戏手机 —— Redmi K40 游戏增强版&#xff0c;这也是K40、K40 Pro、K40 Pro 之后的又一款 K40 产品&#xff0c;主打的是专游戏功能和轻薄设计。Redmi K40 游戏增强版使…

mpvue微信小程序动画_入门微信小程序

为何现在的微信小程序还是高温不退&#xff1f;主要原因如下&#xff1a;无需安装、不占内存、易传播。废话不多说&#xff0c;开始进入开发&#xff01;-----------小程序环境搭建-----------------------------------账号注册百度搜索 "微信公众平台"官网地址&…

瀑布流式布局

今天终于搞懂了瀑布流式布局&#xff0c;哈哈&#xff0c;总结下 瀑布流式布局分为两种类型&#xff1a;1、每一列都限定宽度不限定高度的布局&#xff08;使用浮动&#xff09;2、宽度不是写死的&#xff0c;是根据页面的放大缩小变化的&#xff08;定位布局&#xff09; 瀑布…