[转载] java 计算协方差_Java的深度:通过协方差暴露的API泄漏

参考链接: 关于Java中null的有趣事实

java 计算协方差

 

  

   

  

  

  

  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 {

 

  @Override

  public 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

  @Override

  public AbstractTable join(Table table) {

    return null;

  }

 

  /**

   * Some internal API method, also package private

   */

  void doThings() {}

  void doMoreThings() {

 

    // Use the internal API

    join(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 compiler

    Table table1 = new CustomTable();

    Table join1 = table1.join(joined);

 

    // This works, even if join exposes AbstractTable

    CustomTable table2 = new CustomTable();

    Table join2 = table2.join(joined);

 

    // This doesn't work. The type AbstractTable is not visible

    Table join3 = table2.join(joined).join(joined);

    //            ^^^^^^^^^^^^^^^^^^^ This cannot be dereferenced

 

    // ... so hide these implementation details again

    // The API flaw can be circumvented with casting

    Table 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 计算协方差

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

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

相关文章

gulp之gulp.watch报错

gulpfile.js如下: 问题: 第一次改动文件,监听正常。再次改动,报错,如下: 解决: 总结: 意思,gulpsequence这玩意儿返回的thunk只能执行一次 转载于:https://www.cnblogs.c…

[转载] mybatis

参考链接: 在Java中使用_(下划线)作为变量名 mybatis第一天 1.mybatis概述和环境搭建 mybatis概述 mybatis环境搭建 1. 创建maven工程、添加开发依赖、创建数据库和表; 2. 创建domain实体类和dao mybatis是一门java语言编写持久层框架…

设置了li(float:right),里面的li反过来显示 - 解决办法

设置了li(float:right),里面的li反过来显示 - 解决办法 可以让ul float:right ul里的li 依然float:left 本文转自许琴 51CTO博客,原文链接:http://blog.51cto.com/xuqin/1127540,如需转载请自行联系原作者

[转载] 纯函数和函数柯里化

参考链接: 用示例编写Java柯里化Currying函数 文章目录 纯函数什么是纯函数纯函数例子非纯函数例子 函数柯里化函数柯里化简单例子参数复用 纯函数 什么是纯函数 如果函数的调用参数相同,则永远返回相同的结果。它不依赖于程序执行期间函数外部任何状…

[转载] scala

参考链接: 在Java的数字中使用下划线 1 scala 底层是有一种隐式转换机制,比如对String类型,底层会转化Scala的StringOps类型 2 scala 的通用的化简规则:调方法时候,方法的参数列表只有一个,则方法的&…

MySQL数据库学习笔记

MySQL常用语法总结 一.创建Web数据库 1.登陆到数据库 mysql -h hostname -u username -p mysql -h hostname -u username -D dbname -p 2.创建数据库 CREATE database dbname 3.使用数据库 USE dbname 4.创建数据库表 CREATE TABLE tablename (columns) 5.列的数据 create tabl…

[转载] java实现四种常用排序算法

参考链接: 用Java排序 四种常用排序算法 ##注:从小到大排 ##冒泡排序## 特点:效率低,实现简单 思想:每一趟将待排序序列中最大元素移到最后,剩下的为新的待排序序列,重复上述步骤直到排完所…

[转载] Java复制对象与集合工具类

参考链接: Java中的类和对象 项目中经常需要将某个对象的属性值复制给另一个对象,或者将一个集合复制到另一个集合。利用spring提供的BeanUtils,自己简单封装了一个工具类。 public class CopyUtils { /** * 复制集合 */ public static &l…

.NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)

今天继续利用准备WSE安全开发文章的空闲时间,完善《.NET深入学习笔记》系列(基本都是.Net重要的知识点,我都做了详细的总结,是什么、为什么、和怎么实现)。想必很多人也接触过这两个概念。做过C的人对深浅拷贝的概念一…

VIM一般模式操作

2019独角兽企业重金招聘Python工程师标准>>> vim介绍 vim和vi几乎是一样的,唯一的区别就是当编辑一个文本时,使用vi不会显示颜色,而使用vim会显示颜色。 vim有三个模式:一般模式,编辑模式,命令模…

[转载] 解析Java的JNI编程中的对象引用与内存泄漏问题

参考链接: Java对象如何存储在内存中 JNI,Java Native Interface,是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code;在 native code 中嵌入 Java 虚拟机调用 Java 的…

[转载] java中创建对象的方式

参考链接: 用Java创建对象的不同方法 java中的4种创建对象的方式: 在这片博文中和大家简单分享一下常见的几种创建java对象的方式 1.使用 new 的方式,这也是我们最常见的一种方式 我们以 Person 类来举例说明 例: Person p…

Exchange 2007 SP1 如何定时清理日志???

Exchange 2007 SP1 如何定时清理日志??? 时间:2011-12-31 11:00Tag标签:来源:未知 作者:达思科技 点击: 93次此文章出自: 专业数据恢复 问:Exchange 2007 SP1 如何定时清理日志??&am…

[转载] java-继承和多态

参考链接: Java中的继承 继承: 继承就是保持已有类的特性而构造新类的过程。继承后,子类能够利用父类中定义的变量和方法,就像它们属于子类本身一样。 单继承:在类层次中,子类只继承一个父类的数据结构…

走进SQL Server 2005:备份与恢复功能

每当有任何新的软件发布的时候,你通常都会发现一些你从来不知道或者从来不知道你需要的新的特性。SQL Server 2000中存在的许多的备份和恢复特性都同样保留在了SQL Server 2005中,但是有一些新的提高同样值得你的关注。 镜像备份 SQL Server 2005让你可以…

[转载] Java对返回值的封装

参考链接: 用Java封装 定义自己所需要的返回值类型 public class CodeMsg implements Cloneable { private int retCode; private String message; // 通用异常 public static CodeMsg SUCCESS new CodeMsg(0, "success"); public static CodeMsg EMP…

stateful set 学习笔记

2019独角兽企业重金招聘Python工程师标准>>> 1、创建pv # cat pv.yaml kind: PersistentVolume apiVersion: v1 metadata:name: task-pv-volumelabels:type: local spec:capacity:storage: 3GiaccessModes:- ReadWriteOncehostPath:path: "/tmp/data" 2、…

[转载] Java中对象数组的使用

参考链接: 如何在Java中交换或交换对象 Java对象数组使用 一、Java数组的使用二、Java的对象数组2.1 问题提出2.2 问题解析2.3 问题拆分2.4 代码实现 一、Java数组的使用 对象数组其实和Java的数组类似的,所以要很清楚Java的数组是如何使用的&#xf…

Python自动化开发学习13-联合唯一

联合唯一 联合唯一,就是一个表中的多个字段的组合需要唯一。 使用mysql语句创建 比如创建一张hosts表,记录登录的ip地址或者hostname(表中对应字段host)和 端口号(表中对应字段port),要求host 和…

[转载] Java获取泛型T的类型 T.class

参考链接&#xff1a; Java中的抽象 import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class Main{ public static void main(String[] args) { Foo<String> foo new Foo<String>(){}; // 在类的外部这样获取 Type type ((…