返回顶部
首页 > 资讯 > 后端开发 > Python >Java如何对方法进行调用详解
  • 159
分享到

Java如何对方法进行调用详解

2024-04-02 19:04:59 159人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、方法调用二、非虚方法与虚方法三、调用指令四、解析调用五、分派调用六、静态分派七、动态分派八、单分派与多分派一、方法调用 方法调用的唯一目的:确定要调用哪一个方法 方法调用分为

一、方法调用

方法调用的唯一目的:确定要调用哪一个方法

方法调用分为解析调用和分派调用

二、非虚方法与虚方法

非虚方法: 静态方法,私有方法,父类中的方法,被final修饰的方法,实例构造器

与之对应不是非虚方法的就是虚方法了

它们都没有重写出其他版本的方法,非常适合在类加载阶段就进行解析(符号引用->直接引用)

三、调用指令

普通调用指令

  • invokestatic:调用静态方法
  • invokespecial:调用私有方法,父类中的方法,实例构造器方法,final方法
  • invokeinterface:调用接口方法
  • invokevirtual: 调用虚方法

使用invokestaticinvokespecial指令的一定是非虚方法

使用invokeinterface指令一定是虚方法(因为接口方法需要具体的实现类去实现)

使用invokevirtual指令的是虚方法

动态调用指令

invokedynamic: 动态解析出需要调用的方法再执行

jdk 7 出现invokedynamic,支持动态语言

测试虚方法代码

父类


public class Father {
    public static void staticMethod(){
        System.out.println("father static method");
    }

    public final void finalMethod(){
        System.out.println("father final method");
    }

    public Father() {
        System.out.println("father init method");
    }

    public void overrideMethod(){
        System.out.println("father override method");
    }
}

接口


public interface TestInterfaceMethod {
    void testInterfaceMethod();
}

子类


public class Son extends Father{

    public Son() {
        //invokespecial 调用父类init 非虚方法
        super();
        //invokestatic 调用父类静态方法 非虚方法
        staticMethod();
        //invokespecial 调用子类私有方法 特殊的非虚方法
        privateMethod();
        //invokevirtual 调用子类的重写方法 虚方法
        overrideMethod();
        //invokespecial 调用父类方法 非虚方法
        super.overrideMethod();
        //invokespecial 调用父类final方法 非虚方法
        super.finalMethod();
        //invokedynamic 动态生成接口的实现类 动态调用
        TestInterfaceMethod test = ()->{
            System.out.println("testInterfaceMethod");
        };
        //invokeinterface 调用接口方法 虚方法
        test.testInterfaceMethod();
    }

    @Override
    public void overrideMethod(){
        System.out.println("son override method");
    }

    private void privateMethod(){
        System.out.println("son private method");
    }

    public static void main(String[] args) {
        new Son();
    }
}

注意: 接口中的默认方法也是invokeinterface,接口中的静态方法是invokestatic

四、解析调用

在编译就确定了要调用哪个方法,运行时不可以改变

解析调用 调用的是 非虚方法

五、分派调用

分派又分为静态分派与动态分配

早期绑定:解析调用和静态分派这种编译期间可以确定调用哪个方法

晚期绑定: 动态分派这种编译期无法确定,要到运行时才能确定调用哪个方法

六、静态分派


//  静态类型      	 实际类型
	List list = new ArrayList();

静态分派: 根据静态类型决定方法执行的版本的分派

发生在编译期,特殊的解析调用

典型的表现就是方法的重载


public class StaticDispatch {
    public void test(List list){
        System.out.println("list");
    }

    public void test(ArrayList arrayList){
        System.out.println("arrayList");
    }

    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        List list = new ArrayList();
        StaticDispatch staticDispatch = new StaticDispatch();
        staticDispatch.test(list);
        staticDispatch.test(arrayList);
    }
}

方法的版本并不是唯一的,往往只能确定一个最适合的版本

七、动态分派

动态分派:动态期根据实际类型确定方法执行版本的分派

动态分派与重写有着紧密的联系


public class DynamicDispatch {
    public static void main(String[] args) {
        Father father = new Father();
        Father son = new Son();

        father.hello();
        son.hello();
    }
    static class Father{
        public void hello(){
            System.out.println("Father hello");
        }
    }

    static class Son extends Father{
        @Override
        public void hello() {
            System.out.println("Son hello");
        }
    }
}

虽然常量池中的符号引用相同,invokevirtual指令最终指向的方法却不一样

分析invokevirtual指令搞懂它是如何确定调用的方法

1.invokevirtual找到栈顶元素的实际类型

2.如果在这个实际类型中找到与常量池中描述符与简单名称相符的方法,并通过访问权限的验证就返回这个方法的引用(未通过权限验证返回IllegalAccessException非法访问异常)

3.如果在实际类型中未找到,就去实际类型的父类中寻找(没找到抛出AbstractMethodError异常)

因此,子类重写父类方法时,根据invokevirtual指令规则,先找实际类型,所以才存在重写的多态

频繁的动态分派会重新查找栈顶元素实际类型,会影响执行效率

为提高性能,JVM在该类方法区建立虚方法表使用索引表来代替查找

字段不存在多态

当子类出现与父类相同的字段,子类会覆盖父类的字段


public class DynamicDispatch {
    public static void main(String[] args) {
        Father son = new Son();
    }
    static class Father{
        int num = 1;

        public Father() {
            hello();
        }

        public void hello(){
            System.out.println("Father hello " + num);
        }
    }

    static class Son extends Father{
        int num = 2;

        public Son() {
            hello();
        }

        @Override
        public void hello() {
            System.out.println("Son hello "+ num);
        }
    }
}

先对父类进行初始化,所以会先执行父类中的构造方法,而构造方法去执行了hello()方法,此时的实际类型是Son于是会去执行Son的hello方法,此时子类还未初始化成员变量,只是有个默认值,所以输出Son hello 0

八、单分派与多分派


public class DynamicDispatch {
    public static void main(String[] args) {
        Father son = new Son();
        Father father = new Father();

        son.hello(new Nod());
        father.hello(new Wave());
    }
    static class Father{


        public void hello(Nod nod){
            System.out.println("Father nod hello " );
        }

        public void hello(Wave wave){
            System.out.println("Father wave hello " );
        }
    }

    static class Son extends Father{

        @Override
        public void hello(Nod nod) {
            System.out.println("Son nod hello");
        }

        @Override
        public void hello(Wave wave) {
            System.out.println("Son wave hello");
        }
    }

    //招手
    static class Wave{}
    //点头
    static class Nod{}
}

宗量: 方法参数与方法调用者

分派还可以分为单,多分派

单分派:根据一个宗量选择方法

多分派:根据多个宗量选择方法

在编译时,不仅要关心静态类型是Father还是Son,还要关心参数是Nod还是Wave,所以静态分派是多分派(根据两个宗量对方法进行选择)

在执行son.hello(new Nod())时只需要关心实际类型是Son还是Father,所以动态分派是单分派(根据一个宗量对方法进行选择)

到此这篇关于Java如何对方法进行调用详解的文章就介绍到这了,更多相关Java调用方法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java如何对方法进行调用详解

本文链接: https://lsjlt.com/news/127433.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java如何对方法进行调用详解
    目录一、方法调用二、非虚方法与虚方法三、调用指令四、解析调用五、分派调用六、静态分派七、动态分派八、单分派与多分派一、方法调用 方法调用的唯一目的:确定要调用哪一个方法 方法调用分为...
    99+
    2024-04-02
  • Java对象方法的调用执行过程详解
    目录对象方法的调用执行过程调用方法的几种方式第一种第二种第三种对象方法的调用执行过程 编译器查看对象的声明类型和方法名。假设调用x.f(param),隐式参数为x声明为C类对象,需要...
    99+
    2024-04-02
  • 详解Go语言如何进行Http调用
    目录前言前置知识GET 请求小结前言 无论是微服务还是单体架构等,服务间都有相互通信的时候,而最直接的通信方法就是 HTTP 调用,本文将会介绍在 Go 语言里,如何进行 HTTP ...
    99+
    2022-12-15
    Go语言Http调用 Go Http调用
  • 如何在java中调用xls对xml进行格式化
    本篇文章给大家分享的是有关如何在java中调用xls对xml进行格式化,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在java中调用xls格式化xml 使用javax.xml....
    99+
    2023-05-31
    java xls xml
  • Spring方法中调用异步方法进行事务控制详解
    Spring 异步事务控制 文章目录 Spring 异步事务控制Spring 事务源码逻辑一、事务拦截器拦截二、进行事务控制三、事务开启 / 回滚 /提交操作四、事务完成,清除事务信息简单总结 异步方法事务控制方案一:自身编码...
    99+
    2023-08-20
    spring java 数据库 mysql
  • Java/Web如何调用Hadoop进行MapReduce
    这篇文章主要为大家展示了“Java/Web如何调用Hadoop进行MapReduce”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java/Web如何调用Hadoop进行MapReduce”这篇...
    99+
    2023-05-30
    java hadoop mapreduce
  • php如何对内存进行调整
    这篇文章主要介绍“php如何对内存进行调整”,在日常操作中,相信很多人在php如何对内存进行调整问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php如何对内存进行调整”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-07-05
  • 详解使用Visual Studio Code对Node.js进行断点调试
    在开发的过程中,几乎不可能一次性就能写出毫无破绽的程序,断点调试代码是一个普遍的需求。 作为前端开发工程师,以往我们开发的JavaScript程序都运行在浏览器端,利用Chrome提供的开发者工具就可以方便...
    99+
    2022-06-04
    断点 详解 Visual
  • Java+Selenium调用JavaScript的方法详解
    目录简介调用JavaScript滑动滚动条简介 本文主要讲解java 利用Selenium 操作浏览器网站时候,需要用的js的地方,代码该如何实现。 调用JavaScript web...
    99+
    2023-01-09
    Java Selenium调用JavaScript Selenium调用JavaScript Java Selenium JavaScript
  • Java Eclipse进行断点调试的方法
    如何调试Java程序?大家最开始学习Java,都会觉得IDE调试好高端有木有,其实很简单了。下文会尽量简单直观的教会你在Eclipse中调试,其他的IDE调试步骤也是类似的。在你觉得有错的地方设置断点。在代码行数前,点击右键,注意是右键,然...
    99+
    2023-05-30
    eclipse java 断点调试
  • java中如何调用对方接口
    调用对方http接口步骤:URL url = new URL(path);打开和url之间的连接HttpURLConnection conn = (HttpURLConnection) url.openConnection();设置通用的请...
    99+
    2015-11-19
    java基础 java 调用 接口
  • goLang中如何进行调试操作方法
    这篇文章将为大家详细讲解有关goLang中如何进行调试操作方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。示例如下go get github.com/mailgun/godebugg...
    99+
    2023-06-15
  • php如何调用对象方法
    今天小编给大家分享一下php如何调用对象方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、创建对象在PHP中,调用对象方...
    99+
    2023-07-05
  • 如何在Java中调用python文件执行详解
    目录一、Java内置Jpython库(不推荐)1.1 下载与使用1.2 缺陷二、使用Runtime.getRuntime()执行脚本⽂件2.1 使用2.2 缺陷三、利用cmd调用py...
    99+
    2024-04-02
  • java如何调用js方法
    js方法如下:function add(a,b){ return a + b + number; }调用方法如下:(免费学习视频教程分享:java视频教程)package com.cgnb.dataqualitymng; impor...
    99+
    2017-05-25
    java教程 java 调用 js 方法
  • java如何调用类方法
    要调用类方法,可以使用类名直接调用方法,而不需要创建类的实例对象。例如,假设有一个类名为MathUtils,其中有一个静态方法add...
    99+
    2023-08-18
    java
  • Java如何使用Collections.sort对中文进行排序方式
    本篇文章为大家展示了Java如何使用Collections.sort对中文进行排序方式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。使用Collections.sort对中文进行排序使用collec...
    99+
    2023-06-25
  • Java String对象使用方法详解
    Java String对象使用方法详解先来看一个例子,代码如下: public class Test { public static void main(String[] args) { String str = "abc"; ...
    99+
    2023-05-31
    java string ava
  • Java 方法的定义与调用详解
    目录1.方法概述2.方法的定义和调用2.1 方法定义2.2 方法调用2.3 方法的调用过程2.4 方法练习3.带参数方法的定义和调用3.1带参数方法定义3.2带参数方法调用1.方法概...
    99+
    2024-04-02
  • Python实现调用jar或执行java代码的方法详解
    目录简介安装jpypejava 代码python 调用代码简介 Python 作为一种灵活的软件开发语言在当今被广泛使用。在软件开发过程中,有时需要在 Python 项目中利用既有的...
    99+
    2022-12-21
    Python调用jar Python 执行Java代码 Python jar
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作