JAVA的List接口的remove重载方法调用原理
前言
说真的,平常看源码都是自己看完自己懂,很少有写出来的冲动。
但是在写算法的时候,经常用到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重载方法调用原理的更多相关文章
- 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 ...
- 为什么Java不能以返回值区分重载方法?
读者可能会想:"在区分重载方法的时候,为什么只能以类名和方法的形参列表作为标准呢?能否考虑用方法的返回值来区分呢?" 比如下面两个方法,虽然他们有相同的名字和形式参数,但却很容易区 ...
- java面试题0001-区分类中重载方法的依据是什么?
到底是根据什么来区分类中重载的方法? A:不同的返回值类型. B:不同的参数类型. C:不同的访问权限. D:不同的参数名称. 解析: Step1.我们先在DifferentiateReload类中创 ...
- Java容器---Collection接口中的共有方法
1.Collection 接口 (1)Collection的超级接口是Iterable (2)Collection常用的子对象有:Map.List.Set.Queue. 右图中实现黑框的ArrayLi ...
- java父类与接口有相同的方法
这是java多态的一个体现,如果一个类classA继承了类classB,有实现了接口interfaceA,并且接口中有方法funA(),且父类classB中也有funA(),那么对于classA来说既 ...
- java 请求第三方接口 GET\POST 实现方法
(1)GET方法 /** * 根据高德地图api获取位置信息 * @return * */ public static String getMapAddInfo(String httpurl) { H ...
- 【Java面试题】14 super.getClass()方法调用
下面程序的输出结果是多少? import java.util.Date; public class Test extends Date{ public static void main(String[ ...
- JAVA中,不同工程间的方法调用
可以调用, 用配置构建路径的方法:点选工程1, 点击右键, 选择 Build Path(构建路径) - > Configure Build Path...(配置构建路径...)然后在弹出的窗口中 ...
- 趣谈iOS运行时的方法调用原理
一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...
随机推荐
- SSH项目,JSP项目,SSM项目源码附带环境安装指导视频教程
基于java开发的一个局域网端口扫描程序下载地址:https://www.icodedock.com/article/6.html 用JAVA实现对JAVA代码的格式化下载地址:https://www ...
- 原来JS是这样的 - 对象属性
引子 在上一篇(原来JS是这样的 (2))刚发布的时候就阅读了那篇文章的人可能会注意到那篇曾用过"JavaScript 中万物皆对象"的说法,而在随后我发现错误后立即更新改掉了这个 ...
- Postgresql-rman
联机程序. 并且目标数据库必须处于归档模式. 支持在线全备, 增量备份, 归档备份 增量备份基于已经存在的一个全库备份 rman 本身使用pg_start_backup(), copy, pg_sto ...
- pandas数据分析输出excel产生文本形式存储的百分比数据,如何处理?
关键词: python.pandas.to_excel.文本形式存储的数据 需求描述: 我用 python pandas 写了数据统计与分析脚本,并把计算结果用 pandas 的 to_excel() ...
- 【LeetCode】56-合并区间
题目描述 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 ...
- jinfo Java配置信息工具
jinfo(Configuration info for Java) jinfo的作用是实时地查看和调整虚拟机各项参数. jinfo 命令格式: jinfo [ option ] pid pid是虚拟 ...
- .Ajax(async异步与sync同步)
异步,不会阻碍代码的执行,它会等待所有的同步代码执行完毕后,再执行输出自己的同步结果.(原生js中,只有定时器,DOM,ajax三个东西是异步的.) 同步,代码只会从上到下依次执行,只要一步出错,接下 ...
- Mahout介绍、安装与应用案例
搭建环境 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shiyanlou用户并在系统根目录下创建/app目录,用于存放 Hadoop等组件运行包.因为该目录用于安装h ...
- ubuntu 12.04下访问windows共享文件夹
ubuntu 12.04LTS已经不支持smbfs文件系统,所以不能用mount -smbfs 来映射windows共享文件夹. 常见有两种方法 1.terminal下 mount //192.168 ...
- hadoop高可用安装和原理详解
本篇主要从hdfs的namenode和resourcemanager的高可用进行安装和原理的阐述. 一.HA安装 1.基本环境准备 1.1.1.centos7虚拟机安装,详情见VMware安装Cent ...