亚型多态性应用于元组的危险
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级的记录。
定义元组类型层次结构时要当心
正如我们在前面的示例中看到的, Tuple3
与Tuple2
有很多共同的代码。
由于数十年来的对象定向和多态设计反模式对我们所有人都造成了严重的大脑损害,我们可能认为让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;}// [...]
}
事实是:由于种种原因,这是您最糟糕的事情。 首先,是的。 Tuple2
和Tuple3
都是元组,因此它们确实具有一些共同的特征。 将这些功能归为一个普通的超级类型并不是一个坏主意,例如:
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
扩展了Record1
, Record1
似乎是个好主意,那么第二个查询将突然编译:
// 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>>
的子类型。
结论
Tuple2
和Tuple5
类型基本上是不兼容的类型。 在强类型系统中,您一定不要引诱类似类型或相关类型也应该是兼容类型。
类型层次结构是非常面向对象的,从面向对象的角度来看,我的意思是自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
亚型多态性应用于元组的危险相关推荐
- tcga癌症亚型获取_亚型多态性应用于元组的危险
tcga癌症亚型获取 Java 8具有lambda和stream,但是没有元组,这真是令人遗憾 . 这就是为什么我们在jOOλ中实现了元组-Java 8的缺失部分 . 元组确实是无聊的值类型容器. 本 ...
- tcga癌症亚型获取_将亚型多态性与通用多态性相关联的危险
tcga癌症亚型获取 Java 5已将通用多态性引入Java生态系统. 即使我们都知道由于泛型类型擦除及其后果而引起的无数警告,这还是对Java语言的重要补充. 通用多态性(也称为参数多态性 )通常与 ...
- 将亚型多态性与通用多态性相关联的危险
Java 5已将通用多态性引入Java生态系统. 即使我们都知道由于泛型类型擦除及其后果而引起的无数警告,这对Java语言还是一个很大的补充. 通用多态性(也称为参数多态性 )通常与可能预先存在的亚型 ...
- java安装_Java开发中更多常见的危险信号
java安装 在< Java开发中的常见危险信号>一文中,我介绍了一些不一定本身就是错误或不正确的做法,但它们可能表明存在更大的问题. 这些"红色标记"类似于" ...
- 数据库防火墙——实现数据库的访问行为控制、危险操作阻断、可疑行为审计...
转自百度百科 数据库防火墙系统,串联部署在数据库服务器之前,解决数据库应用侧和运维侧两方面的问题,是一款基于数据库协议分析与控制技术的数据库安全防护系统.DBFirewall基于主动防御机制,实现数据 ...
- Python类的多态和多态性
很多人喜欢将多态与多态性二者混为一谈,然后百思不得其解,其实只要分开看,就会很明朗. 一.多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 序列数据类型有多种形态 ...
- Day20:绑定方法与非绑定办法、多态和多态性
一.绑定方法与非绑定方法 类中定义的函数分成两大类: 1.绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入): 1. 绑定到类的方法:用classmethod装饰器装饰的方法. 为类量身定 ...
- python面向对象:多态与多态性
多态 多态指的是一类事物有多种形态,比如 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物@abc.abs ...
- java 绑定微信号开发_Java开发中的更多常见危险信号
java 绑定微信号开发 在< Java开发中的常见危险信号>一文中,我研究了一些不一定本身就是错误或不正确的做法,但它们可能表明存在更大的问题. 这些"红色标记"类似 ...
最新文章
- 解决Uncaught SyntaxError: Unexpected token var报错问题
- 深度学习和目标检测系列教程 16-300:通过全球小麦数据集训练第一个yolov5模型
- mysql explain用法和结果的含义
- Loj2687,jzoj3320-文本编辑器【线头dp】
- MySql的用户权限
- Leetcode389
- Python3 移动文件——合集
- 先知平台算法原理简介
- Python使用datetime模块进行简单的日期换算与计算
- win7免费升级win10官方工具
- 白嫖UltraEdit、UltraCompare等等类似工具(2021.2.16更新)
- 乒乓球侧旋球MATLAB,【动图】看动图让你了解乒乓球的侧旋转
- 安卓蓝牙设置接收订阅通知断开第二次连接不上或者自动断开status=8的解决办法。
- android摇一摇跳转界面,android摇一摇随机变图片
- 关于车上那几块屏幕的一点思考
- vlan的几种划分方式
- 二手市场回收基于微信小程序和app两种应用开发uniapp
- 利用Qt制作QQ的登录及主界面
- C语言单链表 看不懂temp->next = book; book->next =NULL;
- AMD 硬解码开发(四)之边摸索边编译samples
热门文章
- JAVA多线程总结(笔记)
- from + size must be less than or equal to: [10000] but was [10550]
- Myeclipse 创建web项目的一些基本操作
- 高性能mysql_事务及4种隔离级别
- 工厂模式理解_工厂模式
- spicy命令_Spicy Spring:动态创建自己的BeanDefinition
- idea测试单元错误_不要单元测试错误
- 夏末浅笑_2014年夏末大Java新闻
- java8 函数式编程_您必须学习Java 8的函数式编程吗?
- 通过WAD和Docker热部署Java Enterprise