Java的深度:通过协方差暴露的API泄漏

Java有时可能非常棘手,特别是在API设计中。 让我们看一个非常有趣的展示柜。 jOOQ强烈地将API与实现分开。 所有API都在org.jooq包中,并且是公共的。 大多数实现都在org.jooq.impl包和package-private中。 只有工厂和一些专用的基础实现是公开的。 这允许非常强大的包级封装,几乎只向jOOQ用户公开接口。

包级封装的简化示例

大致来说,jOOQ如何建模SQL表。 (过于简化的)API:

package org.jooq;/*** A table in a database*/
public interface Table {/*** Join two tables*/Table join(Table table);
}

还有两个(过于简化的)实现类:

package org.jooq.impl;import org.jooq.Table;/*** Base implementation*/
abstract class AbstractTable implements Table {@Overridepublic Table join(Table table) {return null;}
}/*** Custom implementation, publicly exposed to client code*/
public class CustomTable extends AbstractTable {
}

内部API的公开方式

假设内部API在协方差方面有一些技巧:

abstract class AbstractTable implements Table, InteralStuff {// Note, this method returns AbstractTable, as it might// prove to be convenient to expose some internal API// facts within the internal API itself@Overridepublic AbstractTable join(Table table) {return null;}/*** Some internal API method, also package private*/void doThings() {}void doMoreThings() {// Use the internal APIjoin(this).doThings();}
}

乍一看,这看起来很安全,是吗? AbstractTable是包私有的,但是CustomTable对其进行了扩展并继承了其所有API,包括“ AbstractTable join(Table)”的协变方法重写。 这会导致什么? 查看以下客户代码

package org.jooq.test;import org.jooq.Table;
import org.jooq.impl.CustomTable;public class Test {public static void main(String[] args) {Table joined = new CustomTable();// This works, no knowledge of AbstractTable exposed to the compilerTable table1 = new CustomTable();Table join1 = table1.join(joined);// This works, even if join exposes AbstractTableCustomTable table2 = new CustomTable();Table join2 = table2.join(joined);// This doesn't work. The type AbstractTable is not visibleTable join3 = table2.join(joined).join(joined);//            ^^^^^^^^^^^^^^^^^^^ This cannot be dereferenced// ... so hide these implementation details again// The API flaw can be circumvented with castingTable join4 = ((Table) table2.join(joined)).join(joined);}
}

结论

篡改类层次结构中的可见性可能很危险。 注意以下事实:在接口中声明的API方法始终是公共的,而不管涉及非公共工件的任何协变实现。 如果API设计人员无法正确处理API用户,这可能会很烦人。

在下一版的jOOQ中已修复

参考: Java的深度:在JAVA,SQL和JOOQ博客中, JCG合作伙伴 Lukas Eder 通过协方差暴露了API泄漏 。


翻译自: https://www.javacodegeeks.com/2012/05/depths-of-java-api-leak-exposed-through.html

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

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

相关文章

StringMVC 中如何做数据校验

步骤一&#xff1a;引入四个jar包 步骤二&#xff1a;注册类型转换器 <context:component-scan base-package"cn.happy.controller"></context:component-scan><!-- 配置验证器 --><bean id"myvalidator" class"org.springframe…

ibm+x3650+m4+linux+raid驱动,IBM X3650M4阵列卡驱动下载

ibm X3650M4raid阵列卡驱动适合安装windowsserver2008,windowsserver2008R2,系统问题&#xff0c;服务器问题&#xff0c;可以联系我们也可以到5分享论坛发帖求助。IBM System x3650 M4服务器是一款应用最为广泛的2U机架服务器&#xff0c;支持Xeon E5-2600机架服务器的所有产品…

为什么在Java 6上Math.round(0.499999999999999917)舍入为1

总览 错误表示错误和算术舍入错误有两种类型&#xff0c;它们在浮点计算中很常见。 在此简单示例中&#xff0c;这两个错误组合在一起&#xff0c;在Java 6中Math.round&#xff08;0.4999999999999999999917&#xff09;舍入为1。 表示错误 浮点数是以2为底的格式&#xff0c…

单利模式

class Singleton{ public:static Singleton* GetInstance(){if (m_pInstance nullptr){m_pInstance new Singleton;}return m_pInstance;} private:Singleton(){}//需要将构造和析构定义成私有的防止外界构造和析构~Singleton(){}static Singleton* m_pInstance;//static所有…

C语言switch中break的作用,C语言中switch...case语句中break的重要性

在C语言中switch...case语句是经常用到的&#xff0c;下面我介绍一下在使用该语句时候需要注意的一个细节问题。话不多说&#xff0c;直接举例子&#xff1a;例子1&#xff1a;switch(fruit){case 1:printf("apple"); break;case 2:printf("banana"); brea…

BZOJ 1898: [Zjoi2005]Swamp 沼泽鳄鱼 [矩阵乘法]

1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1082 Solved: 602[Submit][Status][Discuss]Description 潘塔纳尔沼泽地号称世界上最大的一块湿地&#xff0c;它地位于巴西中部马托格罗索州的南部地区。每当雨季来临&#xff0c;这里碧波荡漾…

从Spring开始,Java EE 6必须具备哪些附加功能?

我是一名高级Java开发人员&#xff0c;必须研究应用程序架构师选择的技术。 我最多只能表达对特定技术的看法&#xff0c;不能做出/影响技术选择的决定。 因此&#xff0c;在我的正式项目中&#xff0c;我别无选择从Spring迁移到JavaEE6或从JavaEE6迁移到Spring。 我坚信&#…

UML类图与类的关系详解

在画类图的时候&#xff0c;理清类和类之间的关系是重点。类的关系有泛化(Generalization)、实现&#xff08;Realization&#xff09;、依赖(Dependency)和关联(Association)。其中关联又分为一般关联关系和聚合关系(Aggregation)&#xff0c;合成关系(Composition)。下面我们…

教程:Hibernate,JPA和Spring MVC –第2部分

本教程将向您展示如何使用基本的Hibernate / JPA应用程序&#xff0c;如何将其转换为Spring MVC Web项目&#xff0c;以便能够在Web浏览器中查看数据库&#xff0c;以及最后使用Spring的Transactional注释来减少样板代码。 本教程假定您熟悉Java和Maven&#xff0c;并且已经完成…

算法转换c语言程序,(转)C语言实现卡尔曼滤波算法程序

非常感谢原作者&#xff0c;我在这个的基础上转换成纯整形运算。STM32F103 12位ADC先放大1000倍再运算&#xff0c;理论上可以保留小数点后三位的结果。效果非常不错&#xff0c;运算速度也快&#xff0c;72M时钟 1-2uS左右(根据MDK周期数)。]uint32_t KalmanFilter(int32_t Re…

Java 8的烹调方式–拼图项目

什么是Project Jigsaw&#xff1a;Project Jigsaw是使Java编译器模块知道的项目。 多年以来&#xff0c;Java API一直是整体的&#xff0c;即从代码的任何部分都可以平等地看到整个API。 还没有任何方法可以声明代码对任何其他用户库的依赖关系。 拼图项目试图以非常有效的方式…

python之路-SQLAlchemy

SQLAchemy SQLAlchemy是Python编程语言下的一款ORM框架&#xff0c;该框架建立在数据库API之上&#xff0c;使用关系对象映射进行数据库操作&#xff0c;简言之便是&#xff1a;将对象转换成SQL&#xff0c;然后使用数据API执行SQL并获取执行结果。 安装&#xff1a; pip3 inst…

POJ 1751 Highways

题意&#xff1a;n个城市&#xff0c;然后把n个城市的坐标都给你&#xff0c;然后给你m条已经修好的道路&#xff0c;然后给出m个已经修好道路的城市a&#xff0c;b&#xff0c; However, they want to guarantee that every town is highway-reachable from every other town.…

C语言编程中void什么意思,程序设计中遇到的void到底是什么意思

部分编程的初学者都会问"void是什么意思","为什么很多函数前都要加个void".实际上,void最简单的解释就是把0转换成空类型的意思。下面用各个开发语言来详解void1.C语言中的void表示空类型&#xff0c;它跟int&#xff0c;float是同地位的&#xff0c;一般用…

Linux中vim编辑器的缩进的功能键

vim编程时,经常需要对代码进行缩进处理,以增加程序的可读性和后期的代码维护. 可以采用多种方式达到缩进的目的: 1) 命令模式(command mode) 2) Visual模式&#xff08;visual mode&#xff09; 2) 输入模式(entry mode) 3) 末行模式(last-line mode) 4) 在/etc/vimrc有给予vim…

JSF 2,PrimeFaces 3,Spring 3和Hibernate 4集成项目

本文展示了如何集成JSF2&#xff0c;PrimeFaces3&#xff0c;Spring3和Hibernate4技术。 它为Java开发人员提供了一个通用的项目模板。 另外&#xff0c;如果Spring不用于业务和数据访问层&#xff0c;则可以提供JSF – PrimeFaces和Hibernate集成项目。 二手技术&#xff1a…

c语言编程文件中删除数据结构,C语言数据结构实战(一)顺序表的插入与删除

今天学习了思成老师的数据结构实战教程 写了一个顺序表 插入和删除的操作 把源码共享给大家 一共包括list.c stu.h main.c list.h .h文件是头文件 需要引入 具体的功能我都已经在代码中写明了list.h代码如下&#xff1a;//线性表的定义在头文件中实现#ifndef _LIST_H#define …

内存使用分析工具Valgrind简单用法

转载自 http://www.cnblogs.com/sunyubo/archive/2010/05/05/2282170.html 暂时还未使用过&#xff0c;记录下&#xff0c;记录下&#xff0c;记录下 Valgrind的主要作者Julian Seward刚获得了今年的Google-OReilly开源大奖之一──Best Tool Maker。让我们一起来看一下他的作品…

Lucene概述第一部分:创建索引

介绍 我最近一直在与开源搜索引擎Lucene合作 。 我不是专家&#xff0c;但是由于我只是浏览了一些相当稀疏的文档并将应用程序从Lucene的很旧的版本迁移到了最新版本的2.4&#xff0c;所以我在总体上很清楚。 Lucene的文档有点让人难以想象&#xff0c;因此我想趁此机会在我脑海…

初识openstack

一、 什么是openstack&#xff1f; OpenStack是一个由NASA&#xff08;美国国家航空航天局&#xff09;和Rackspace合作研发并发起的&#xff0c;以Apache许可证授权的自由软件和开放源代码项目。 二、openstack前世今身 openstack是一个跟Eucalyptus,AWS(Amazon web Service)类…