前言

说真的,平常看源码都是自己看完自己懂,很少有写出来的冲动。

但是在写算法的时候,经常用到java中各种集合,其中也比较常用到remove方法。

remove有重载函数,分别传入参数是索引index或者数据Object(指定泛型后自动转换),如果指定泛型是其他数据类型还好,但是指定的是Integer或者是int的话,或者就有点懵了。

这曾经也困惑过我,所以我就唯有用实践解惑了。

测试类设计

  • 测试类一
public class Text {

    public void remove(int index){
System.out.println("调用传参为int的remove方法");
} public void remove(Integer object){
System.out.println("调用传参为Integer的remove方法");
} public void remove(Object object){
System.out.println("调用传参为Object的remove方法");
}
}
  • 测试类二
public class Text {

    public void remove(Integer object){
System.out.println("调用传参为Integer的remove方法");
} public void remove(Object object){
System.out.println("调用传参为Object的remove方法");
}
}
  • 测试类三
public class Text {

    public void remove(Object object){
System.out.println("调用传参为Object的remove方法");
}
}

结果

三个测试类分别传入int,Integer,Object型变量,观察效果。

  • 测试类一

传入类型为int:调用传参为int的remove方法

传入类型为Integer:调用传参为Integer的remove方法

传入类型为Object:调用传参为Object的remove方法

  • 测试类二

传入类型为int:调用传参为Integer的remove方法

传入类型为Integer:调用传参为Integer的remove方法

传入类型为Object:调用传参为Object的remove方法

  • 测试类三

传入类型为int:调用传参为Object的remove方法

传入类型为Integer:调用传参为Object的remove方法

传入类型为Object:调用传参为Object的remove方法

从输出结果可以看出,当方法的传参的类层级逐渐变高时,层级较低的传参会进行向上转型适应传参的需要。

原因分析

下面我们先反编译各测试类的源码,结果如下

  • 测试类一

invokevirtual #11 // Method remove:(I)V

invokevirtual #15 // Method remove:(Ljava/lang/Integer;)V

invokevirtual #18 // Method remove:(Ljava/lang/Object;)V

  • 测试类二

invokevirtual #11 // Method remove:(Ljava/lang/Integer;)V

invokevirtual #11 // Method remove:(Ljava/lang/Integer;)V

invokevirtual #17 // Method remove:(Ljava/lang/Object;)V

  • 测试类三

invokevirtual #10 // Method remove:(Ljava/lang/Object;)V

invokevirtual #10 // Method remove:(Ljava/lang/Object;)V

invokevirtual #10 // Method remove:(Ljava/lang/Object;)V

可以看出,反编译代码中都是调用实例方法的命令,所以结果中自动"向上转型"其实是jvm的功劳。jvm通过在编译时确定调用的传参类型,静态分派到具体方法的。

所以在前言中的困惑已经解除了,就是由于jvm中静态分派的实现,调用次序是int->Integer->Object。

后记

也没什么想说的,感觉在阅读源码的时候必须多想想为什么这样做,为什么要这样实现,同时通过断点或者反编译的手段找出自己的答案。keep going!

本文首发于cartoon的博客

转载请注明出处:https://cartoonyu.github.io/cartoon-blog/post/java/java的list接口的remove重载方法调用原理/

JAVA的List接口的remove重载方法调用原理的更多相关文章

  1. java读取PHP接口数据的实现方法(四)

    PHP文件: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 3 ...

  2. 为什么Java不能以返回值区分重载方法?

    读者可能会想:"在区分重载方法的时候,为什么只能以类名和方法的形参列表作为标准呢?能否考虑用方法的返回值来区分呢?" 比如下面两个方法,虽然他们有相同的名字和形式参数,但却很容易区 ...

  3. java面试题0001-区分类中重载方法的依据是什么?

    到底是根据什么来区分类中重载的方法? A:不同的返回值类型. B:不同的参数类型. C:不同的访问权限. D:不同的参数名称. 解析: Step1.我们先在DifferentiateReload类中创 ...

  4. Java容器---Collection接口中的共有方法

    1.Collection 接口 (1)Collection的超级接口是Iterable (2)Collection常用的子对象有:Map.List.Set.Queue. 右图中实现黑框的ArrayLi ...

  5. java父类与接口有相同的方法

    这是java多态的一个体现,如果一个类classA继承了类classB,有实现了接口interfaceA,并且接口中有方法funA(),且父类classB中也有funA(),那么对于classA来说既 ...

  6. java 请求第三方接口 GET\POST 实现方法

    (1)GET方法 /** * 根据高德地图api获取位置信息 * @return * */ public static String getMapAddInfo(String httpurl) { H ...

  7. 【Java面试题】14 super.getClass()方法调用

    下面程序的输出结果是多少? import java.util.Date; public class Test extends Date{ public static void main(String[ ...

  8. JAVA中,不同工程间的方法调用

    可以调用, 用配置构建路径的方法:点选工程1, 点击右键, 选择 Build Path(构建路径) - > Configure Build Path...(配置构建路径...)然后在弹出的窗口中 ...

  9. 趣谈iOS运行时的方法调用原理

    一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...

随机推荐

  1. SSH项目,JSP项目,SSM项目源码附带环境安装指导视频教程

    基于java开发的一个局域网端口扫描程序下载地址:https://www.icodedock.com/article/6.html 用JAVA实现对JAVA代码的格式化下载地址:https://www ...

  2. 原来JS是这样的 - 对象属性

    引子 在上一篇(原来JS是这样的 (2))刚发布的时候就阅读了那篇文章的人可能会注意到那篇曾用过"JavaScript 中万物皆对象"的说法,而在随后我发现错误后立即更新改掉了这个 ...

  3. Postgresql-rman

    联机程序. 并且目标数据库必须处于归档模式. 支持在线全备, 增量备份, 归档备份 增量备份基于已经存在的一个全库备份 rman 本身使用pg_start_backup(), copy, pg_sto ...

  4. pandas数据分析输出excel产生文本形式存储的百分比数据,如何处理?

    关键词: python.pandas.to_excel.文本形式存储的数据 需求描述: 我用 python pandas 写了数据统计与分析脚本,并把计算结果用 pandas 的 to_excel() ...

  5. 【LeetCode】56-合并区间

    题目描述 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 ...

  6. jinfo Java配置信息工具

    jinfo(Configuration info for Java) jinfo的作用是实时地查看和调整虚拟机各项参数. jinfo 命令格式: jinfo [ option ] pid pid是虚拟 ...

  7. .Ajax(async异步与sync同步)

    异步,不会阻碍代码的执行,它会等待所有的同步代码执行完毕后,再执行输出自己的同步结果.(原生js中,只有定时器,DOM,ajax三个东西是异步的.) 同步,代码只会从上到下依次执行,只要一步出错,接下 ...

  8. Mahout介绍、安装与应用案例

        搭建环境 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shiyanlou用户并在系统根目录下创建/app目录,用于存放 Hadoop等组件运行包.因为该目录用于安装h ...

  9. ubuntu 12.04下访问windows共享文件夹

    ubuntu 12.04LTS已经不支持smbfs文件系统,所以不能用mount -smbfs 来映射windows共享文件夹. 常见有两种方法 1.terminal下 mount //192.168 ...

  10. hadoop高可用安装和原理详解

    本篇主要从hdfs的namenode和resourcemanager的高可用进行安装和原理的阐述. 一.HA安装 1.基本环境准备 1.1.1.centos7虚拟机安装,详情见VMware安装Cent ...