Java的深度:通过协方差暴露的API泄漏
包级封装的简化示例
大致来说,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
Java的深度:通过协方差暴露的API泄漏相关推荐
- java 计算协方差_Java的深度:通过协方差暴露的API泄漏
java 计算协方差 Java有时可能非常棘手,特别是在API设计中. 让我们看一个非常有趣的展示柜. jOOQ强烈地将API与实现分开. 所有API都在org.jooq包中,并且是公共的. 大多数实 ...
- [转载] java 计算协方差_Java的深度:通过协方差暴露的API泄漏
参考链接: 关于Java中null的有趣事实 java 计算协方差 Java有时可能非常棘手,特别是在API设计中. 让我们看一个非常有趣的展示柜. jOOQ强烈地将API与实现分开. 所有API都在 ...
- 用 Java 训练深度学习模型,原来这么简单
作者 | DJL-Keerthan&Lanking 来源 | HelloGitHub 头图 | CSDN下载自东方IC 前言 很长时间以来,Java 都是一个很受企业欢迎的编程语言.得益于丰富 ...
- Java培训深度学习都要学什么
java的知识点有很多,如果是有java基础的同学,进行深度学习是非常有必要的,比较职场技能更新迭代非常的快,那么java培训深度学习都要学什么呢?来看看下面的详细介绍. Java培训深度学习都要学什 ...
- 【深度学习】利用一些API进行图像数据增广
[深度学习]利用一些API进行图像数据增广 文章目录 [深度学习]利用一些API进行图像数据增广 1 先送上一份最强的翻转代码(基于PIL) 2 Keras中的数据增强API种类概述 3 特征标准化 ...
- java.lang.NoSuchMethodError: org.apache.flink.table.api.TableColumn.isGenerated()Z
完整报错如下: select * from dim_behavior; [ERROR] Could not execute SQL statement. Reason: java.lang.NoSuc ...
- Cannot resolve method ‘call(java.lang.String, org.apache.flink.table.api.ApiExpression)‘
intellij提示: Cannot resolve method 'call(java.lang.String, org.apache.flink.table.api.ApiExpression)' ...
- java asm tree_使用ASM 4处理Java类文件–第二部分:Tree API
java asm tree 什么是ASM树API: ASM树API是ASM的一部分,可让您创建/修改内存中的类. 该类被视为信息树. 像整个类一样,它是ClassNode的实例,其中包含FieldNo ...
- Java EE 7中的WebSocket客户端API
在本文中,让我们探索谈论较少的Web Socket Client API,以及如何在Java EE 7容器本身中利用它. Web套接字服务器API规则 JSR 356的服务器端API(Java的Web ...
最新文章
- java swing 架构_Java Swing1 基本框架
- zlib 离线安装_黑板派Python扩展库安装与常见问题解决完整指南
- 如何配置php的ip地址吗,linux如何配置IP
- java技术简介英文_Java技术常见的英文缩写
- JavaScript -- DOM树
- Android源码kernel编译
- 找出区间偶数c语言,c语言实践输出某个区间中不是3的倍数的偶数
- linux:查看使用中的端口
- latex制作中英文简历(含模板代码)
- matlab将txt转成dat,将matlab中数据保存为txt或dat格式
- 比较 SVFI-RIFE 和 DAIN-APP 补针效果 施工中 ~
- 用HTML开发Windows桌面应用程序
- Eclipse的乱码问题是如何解决的
- android起始页面与导航页面
- 周期循环图像边界算法
- 如何快速准备面试中的算法,获得 Offer?
- 情感分析方法之nltk情感分析器和SVM分类器(二)
- 微信小程序之天气查询小案例
- 测试小白基于java的selenium自动化测试环境搭建
- UML画图工具-Graphviz和PlantUML
热门文章
- java安全——数字签名+代码签名
- 构建器设计模式_创新设计模式:构建器模式
- deprecated_@Deprecated新外观可能是什么?
- 工程模式和抽象工厂模式_功能工厂模式
- jboss 4.3.0_JBoss BPM Suite 6.0.3版本的5个实用技巧
- docker 部署java_使用Java EE 7,WildFly和Docker进行持续部署–(第1部分)
- Servlet和JSP之间的区别
- 如何在CircleCI上构建支持Graal的JDK8?
- spring预加载与懒加载_通过Spring将继承树加载到List中
- 雅加达EE:干净的板岩