CN116048731A - 代码处理方法、装置、电子设备及存储介质 - Google Patents
代码处理方法、装置、电子设备及存储介质 Download PDFInfo
- Publication number
- CN116048731A CN116048731A CN202310152286.4A CN202310152286A CN116048731A CN 116048731 A CN116048731 A CN 116048731A CN 202310152286 A CN202310152286 A CN 202310152286A CN 116048731 A CN116048731 A CN 116048731A
- Authority
- CN
- China
- Prior art keywords
- class
- parent
- calling
- interface
- information
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/455—Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
- G06F9/45504—Abstract machines for programme code execution, e.g. Java virtual machine [JVM], interpreters, emulators
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/455—Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
- G06F9/45533—Hypervisors; Virtual machine monitors
- G06F9/45558—Hypervisor-specific management and integration aspects
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
本申请提供一种代码处理方法、装置、电子设备及存储介质,该方法通过获取应用程序的执行参数涉及的jar包,并对jar包进行预处理,得到jar包中涉及继承的类名、类与实现相关的信息、类与继承相关的信息,并根据涉及继承的类名、类与继承相关的信息,确定涉及继承的类中父类的方法与子类的方法之间的调用关系,之后根据类与实现相关的信息,确定接口调用实现类的方法的调用关系,最后输出父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系。该技术方案能够通过代码静态分析的方式,不需要执行代码,就能获取代码实际运行时涉及继承与实现的方法调用关系,使得获取到的方法调用关系与代码实际运行时更接近,结果更准确。
Description
技术领域
本申请涉及计算机技术领域,尤其涉及一种代码处理方法、装置、电子设备及存储介质。
背景技术
在Java虚拟机指令中,有多个指令用于方法调用,这些指令中包含了被调用方法类名、方法名、参数信息等在常量池中的索引,通过调用指令的信息,可以获取到被调用方法的详细信息。
在现有技术中,获取Java方法调用关系的方式为:使用Java开发工具包提供的方法打开jar包或war包,并遍历其中的每个文件,对当前class文件对应的类进行解析,之后遍历当前处理的类中定义的方法的每一条指令,若当前指令属于方法调用指令,则通过方法调用指令获取对应的被调用方法信息,最后将以上不同方法之间的调用关系记录到文件。
然而,上述方法获取被调用方法的信息,在多数场景下能够获取到Java方法调用关系,但存在一些场景无法获取到调用关系,包括子类继承父类、类实现接口等,也即获取到的方法调用关系不完整,会导致以方法调用关系为基础的其他分析不准确的情况发生。
发明内容
本申请提供一种代码处理方法、装置、电子设备及存储介质,以解决现有技术中获取到的方法调用关系不完整等问题。
第一方面,本申请实施例提供了一种代码处理方法,包括:
获取应用程序的执行参数涉及的jar包;
对所述jar包进行预处理,得到所述jar包中涉及继承的类名、类与实现相关的信息、所述类与继承相关的信息;
根据所述涉及继承的类名、所述类与继承相关的信息,确定所述涉及继承的类中父类的方法与子类的方法之间的调用关系;
根据所述类与实现相关的信息,确定接口调用实现类的方法的调用关系;
输出所述父类的方法与子类的方法之间的调用关系,和所述接口调用实现类的方法的调用关系。
第二方面,本申请实施例提供了一种代码处理装置,包括:
获取模块,用于获取应用程序的执行参数涉及的jar包;
处理模块,用于对所述jar包进行预处理,得到所述jar包中涉及继承的类名、类与实现相关的信息、所述类与继承相关的信息;
第一确定模块,用于根据所述涉及继承的类名、所述类与继承相关的信息,确定所述涉及继承的类中父类的方法与子类的方法之间的调用关系;
第二确定模块,用于根据所述类与实现相关的信息,确定接口调用实现类的方法的调用关系;
输出模块,用于输出所述父类的方法与子类的方法之间的调用关系,和所述接口调用实现类的方法的调用关系。
第三方面,本申请提供一种电子设备,包括:处理器,以及与所述处理器通信连接的存储器和收发器;
所述存储器存储计算机执行指令;所述收发器,用于收发数据;
所述处理器执行所述存储器存储的计算机执行指令,以实现如上述第一方面或任一种方式所述的方法。
第四方面,本申请提供一种计算机可读存储介质,所述计算机可读存储介质中存储有计算机执行指令,所述计算机执行指令被处理器执行时用于实现上述第一方面或任一种方式所述的方法。
本申请提供的代码处理方法、装置、电子设备及存储介质,该方法通过获取应用程序的执行参数涉及的jar包,并对jar包进行预处理,得到jar包中涉及继承的类名、类与实现相关的信息、类与继承相关的信息,并根据涉及继承的类名、类与继承相关的信息,确定涉及继承的类中父类的方法与子类的方法之间的调用关系,之后根据类与实现相关的信息,确定接口调用实现类的方法的调用关系,最后输出父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系。该技术方案中根据接口与类之间的继承与实现关系,构建接口与实现类之间,子类与父类之间的实现/继承关系树,结合各接口与类中实现的方法信息,获得未包含在方法调用指令中的接口到实现类、父类到子类、子类到父类的方法调用关系。最终能够通过代码静态分析的方式,不需要执行代码,就能获取代码实际运行时涉及继承与实现的方法调用关系,以使得获取到的方法调用关系与代码实际运行时更接近,结果更准确。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本申请的实施例,并与说明书一起用于解释本申请的原理。
图1为本申请实施例提供的现有技术中调用关系的流程示意图;
图2为本申请实施例提供的代码处理方法的流程示意图一;
图3为本申请实施例提供的代码处理方法的流程示意图二;
图4为本申请实施例提供的代码处理方法的流程示意图三;
图5A为本申请实施例提供的代码处理方法的流程示意图四;
图5B为本申请实施例提供的父类-子类结构树示意图一;
图5C为本申请实施例提供的父类-子类结构树示意图二;
图5D为本申请实施例提供的父类-子类结构树示意图三;
图5E为本申请实施例提供的父类的子类类名映射结构示意图;
图5F为本申请实施例提供的父类与子类处理示意图;
图6为本申请实施例提供的代码处理方法的流程示意图五;
图7为本申请实施例提供的代码处理方法总流程示意图;
图8为本申请实施例提供的涉及继承的类名、及类与实现相关的信息的确定方式流程图;
图9为本申请实施例提供的类与继承相关的信息的确定方式流程图;
图10为本申请实施例提供的父类方法与子类方法之间的调用关系的确定方式流程图;
图11为本申请实施例提供的接口调用实现类的方法的调用关系的确定方式流程图;
图12为本申请实施例提供的代码处理装置实施例的结构示意图;
图13为本申请实施例提供的电子设备的结构示意图。
通过上述附图,已示出本公开明确的实施例,后文中将有更详细的描述。这些附图和文字描述并不是为了通过任何方式限制本公开构思的范围,而是通过参考特定实施例为本领域技术人员说明本公开的概念。
具体实施方式
为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
在介绍本申请的实施例之前,首先对本申请实施例的专业名词进行解释:
Java虚拟机(Java Virtual Machine,JVM):是一个抽象的计算机。像真正的计算机一样,它有一个指令集并在运行时操纵各种内存区域。
Java虚拟机指令:对于计算机处理器而言,指令是一段包含了需要由处理器执行的步骤的代码。计算机必须在接受到指令后才能知道需要进行什么操作。Java虚拟机是一种抽象的计算机,像真正的计算机一样,也具有指令集。
Java开发工具包(Java Development Kit,JDK):是使用Java编程语言构建应用程序等的开发环境。
jar包:将Java工程的.java文件编译为.class文件后,将.class文件及其他配置文件压缩为后缀为.jar的压缩包,可在其他Java工程中直接使用相关代码的功能。
war包:与jar包的格式类似,但war包通常用于Web项目,其中通常还包含Web项目中使用的html等静态资源文件,可在Java Servlet容器中进行部署并提供Web服务功能。
class文件:由Java虚拟机执行的编译代码使用独立于硬件和操作系统的二进制格式表示,通常(但不一定)存储在文件中,称为class文件格式。class文件中包含Java虚拟机指令(或字节码)和符号表,以及其他辅助信息。
其次,对本申请实施例的背景技术进行介绍:
在Java虚拟机指令中,以下五个指令用于方法调用:
1、invokevirtual指令:调用对象的实例方法,在对象的(虚拟)类型上进行调度。这是Java语言中的常规方法分派方式。
2、invokeinterface指令:调用接口方法,搜索特定运行时对象实现的方法以找到合适的方法。
3、invokespecial指令:调用需要特殊处理的实例方法,例如实例初始化方法、私有方法、父类方法等。
4、invokestatic指令:调用命名类中的类(静态)方法。
5、invokedynamic指令:调用动态方法。
以上方法调用指令中包含了被调用方法类名、方法名、参数信息等在常量池中的索引,通过方法调用指令的信息,可以获取到被调用方法的详细信息。
gousiosg/java-callgraph项目支持生成Java方法调用关系,该项目使用ApacheCommons BCEL(Byte Code Engineering Library),通过静态方式解析Java class文件字节码,用于获取Java方法调用关系。gousiosg/java-callgraph项目使用BCEL解析Javaclass文件字节码并获取Java方法调用关系的步骤如图1所示(图1为本申请实施例提供的现有技术中调用关系的流程示意图):
步骤11、使用JDK提供的方法打开指定的jar包/war包,并遍历其中的.class文件;
步骤12、对于.class文件,使用BCEL提供的方法对当前.class文件对应的类进行解析;
步骤13、遍历当前处理的类中定义的方法的每一条指令,若当前指令属于方法调用指令,则通过方法调用指令获取对应的被调用方法信息;
步骤14、将以上不同方法之间的调用关系记录到文件。
gousiosg/java-callgraph项目在获取Java方法调用关系时,通过分析Java虚拟机方法调用指令获取被调用方法的信息,在多数场景下能够获取到Java方法调用关系,但存在一些场景无法获取到调用关系,包括子类继承父类、类实现接口等,导致只能获取到调用父类或接口的方法调用关系,无法获取到调用子类或实现类的方法调用关系,最终获取到的方法调用关系不完整,可能丢失部分重要信息,会导致以方法调用关系为基础的分析结果不准确。
gousiosg/java-callgraph项目仅根据方法调用指令获取方法间的调用关系,在子类继承父类、类实现接口等场景下无法获取到,主要原因如下述:
第一种、接口/父类调用实现类/子类方法调用关系丢失:
在Java中,接口可以继承其他接口,类可以继承其他类,或实现接口。
以下为最简单情况的示例:
1、子类继承父类。例如ChildClass1类继承SuperClass1类;
2、类实现接口。例如ImplClass1类实现Interface1接口。
以下为复杂情况的示例:
1、父类实现接口,子类继承父类。例如SuperClass1类实现Interface1接口,ChildClass1类继承SuperClass1类,ChildClass1A类继承ChildClass1类;
2、子接口继承父接口,父类实现子接口,子类继承父类。例如Interface1A接口继承Interface1接口,SuperClass1类实现Interface1A接口,ChildClass1类继承SuperClass1类。
类中的对象在定义时,可以使用接口或父类的类型,在执行过程中对象可以实例化为相关的任意实现类或子类的类型,在使用Spring框架,或自定义代码时,都可能出现这种情况。Java代码在编译为class文件时,方法调用指令中被调用对象类型为其定义时的类型(接口或父类),不是实际运行时的类型(实现类或子类)。在以上情况下,gousiosg/java-callgraph根据方法调用指令获取相关调用关系时,只能获取到调用者方法调用接口或父类的调用关系,调用者方法调用实际的实现类或子类的调用关系无法获取到,导致方法调用关系丢失。
这是因为根据Java类的字节码进行静态分析时,无法根据方法调用指令获取到实际运行时类的方法之间的调用关系。
示例如下:
存在接口CalleeInterface1,CalleeClass1为其实现类,在CallerClass2类中,定义了类型为CalleeInterface1的对象,在CallerClass2.test2()方法中,调用了CalleeInterface1.test1()方法。在实际执行时,CallerClass2类中的类型为CalleeInterface1的对象会被替换为CalleeClass1类的实例,CallerClass2.test2()方法调用的是CalleeClass1.test1()方法。
以上Java代码在实际执行时,存在调用者方法调用实现类方法的调用关系,如下所示:
“CallerClass2.test2()->CalleeClass1.test1()”
gousiosg/java-callgraph只能获取到调用者方法调用接口方法的调用关系,如下所示:
“CallerClass2.test2()->CalleeInterface1.test1()”
第二种、子类调用父类方法调用关系丢失:
在Java代码中,可在父类中实现方法,在子类中调用父类中的方法。
在这种情况下,gousiosg/java-callgraph根据方法调用指令获取子类中的相关调用关系时,只能获取到子类中的调用者方法调用子类方法的调用关系,子类中的调用者方法调用父类方法的调用关系无法获取到,导致方法调用关系丢失。
这是因为子类的字节码中未定义相关的方法,根据Java类的字节码进行静态分析时,无法根据方法调用指令获取到子类调用父类方法的调用关系。
示例如下:
存在父类SuperClass1,ChildClass1为其子类,在父类中定义了方法testSuper(),在子类中未重载该方法。在子类的test1()方法中,调用了testSuper()方法。在实际执行时,子类的test1()方法调用的testSuper()方法是父类中的。
以上Java代码在实际执行时,存在子类方法调用父类方法的调用关系,如下所示:
“ChildClass1.test1()->SuperClass1.testSuper()”
gousiosg/java-callgraph只能获取到子类方法调用子类方法的调用关系,如下所示:
“ChildClass1.test1()->ChildClass1.testSuper()”
针对现有技术中存在的技术问题,本申请发明人的构思如下:在获取Java程序的方法调用关系时,可以通过静态分析或动态分析的方式实现。若使用动态分析的方式分析,则需要执行代码,通常会使用插桩技术获取代码的执行情况。若需要使代码的每个分支都能够执行到,需要针对每一种情况构建输入数据,工作量会非常大,通常是无法实现的;即使能够实现,也需要耗费大量的时间。若使用静态分析的方式分析,可以根据Java程序的字节码指令获取方法调用信息,不需要执行代码,就能在短时间内获取到全部的方法调用关系。这是静态分析相比动态分析方式最大的优势。
进而,对于gousiosg/java-callgraph项目无法完整获取子类继承父类、类实现接口等场景的调用关系的问题,在获取方法调用关系时,不只是通过Java虚拟机方法调用指令进行获取,还对代码的实际运行情况进行了模拟,结合方法调用指令之外的信息,对方法调用关系进行补充,具体的,根据接口与类之间的继承与实现关系,构建接口与实现类之间,子类与父类之间的实现/继承关系树,结合各接口与类中实现的方法信息,获得接口到实现类、父类到子类、子类到父类的方法调用关系,这些调用关系都超出了方法调用指令能够反映的信息。最终能够通过代码静态分析的方式,不需要执行代码,就能获取代码实际运行时涉及继承与实现的方法调用关系,获取到的方法调用关系更加完整。
下面,通过具体实施例对本申请的技术方案进行详细说明。需要说明的是,下面这几个具体的实施例可以相互结合,对于相同或相似的概念或过程可能在某些实施例中不再赘述。
具体的,图2为本申请实施例提供的代码处理方法的流程示意图一,如图2所示,该方法可以包括如下步骤:
步骤21、获取应用程序的执行参数涉及的jar包。
在本步骤中,应用程序执行时使用的参数中,可以指定多个需要处理的jar包文件路径,当前步骤会获取程序执行参数中指定的需要处理的jar包列表,之后对于每个jar包依次执行后续的处理。
步骤22、对jar包进行预处理,得到jar包中涉及继承的类名、类与实现相关的信息、类与继承相关的信息。
在本步骤中,为了后续能够确定出父类方法与子类方法之间的调用关系,以及接口调用实现类的方法的调用关系,在对上述确定出的jar包中的类的方法调用关系进行处理之前,还需要对jar包进行预处理,以获取到涉及继承的类名、类与实现相关的信息、类与继承相关的信息。
可选的,类与实现相关的信息可以包括:类中实现接口的方法、以及接口中被类实现的方法;类与继承相关的信息可以包括:父类对应的子类列表、子类的父类信息、父类中可被子类重载的方法、子类中可能是重载了父类的方法等信息。
步骤23、根据涉及继承的类名、类与继承相关的信息,确定涉及继承的类中父类的方法与子类的方法之间的调用关系。
在本步骤中,由于Java不支持多继承,每个类只能继承一个类,因此每个类有且仅有一个父类,根据已经得到的涉及继承的类名,在类与继承相关的信息中确定出父类的方法与子类的方法之间的调用关系。
在该步骤之前,还可以包括如下方法:若涉及继承的类中当前方法对应的目标指令为方法调用指令,根据方法调用指令的属性,从常量池中获取被目标指令调用的方法名称、被目标指令调用的对象类型、被目标指令调用的每个参数的类型,以得到当前方法与其他方法的调用关系。
可选的,在处理涉及继承的类中的某个方法时,对方法中的指令进行遍历,假如某个指令为Invokevirtual、invokeinterface、invokespecial、invokestatic、invokedynamic等方法调用指令,则根据方法调用指令的属性,从常量池中获取被调用的方法名称、被调用的对象类型、被调用的每个参数的类型,可以获取到当前类被处理的当前方法对其他方法的调用关系。
例如,当前正在处理的类为Class1,该类中存在方法method1、method2等方法。在处理到method1方法时,该方法中存在instruction1、instruction2、instruction3、instruction4等指令,其中instruction1与instruction3指令为方法调用指令,分别对应ClassA.methoda(String)、ClassB.methodb(int)方法,即可获取到Class1.method1()方法调用ClassA.methoda(String)、ClassB.methodb(int)方法的调用关系。
步骤24、根据类与实现相关的信息,确定接口调用实现类的方法的调用关系。
在本步骤中,在涉及继承的类中,补充父类方法与子类方法之间的调用关系之后,还需要根据上述根据类与实现相关的信息,补充接口调用实现类的方法的调用关系。
步骤25、输出父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系。
在本步骤中,在上述确定出父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系之后,还需要将父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系输出,供其他以方法调用关系为基础的分析使用。
在一种可能的实现中,将父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系输出至结果文件中。
此外,在上述步骤中得到当前方法与其他方法的调用关系之后,还可以输出当前方法与其他方法的调用关系。
在一种可能的实现中,将当前方法与其他方法的调用关系输出至结果文件中。
也即,将获取到的全部方法调用关系输出到结果文件中,包括从Java虚拟机方法调用指令中获取的方法调用关系,以及上述实施例补充的子类继承父类、类实现接口相关的方法调用关系,即父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系。
本申请提供的代码处理方法,通过获取应用程序的执行参数涉及的jar包,并对jar包进行预处理,得到jar包中涉及继承的类名、类与实现相关的信息、类与继承相关的信息,并根据涉及继承的类名、类与继承相关的信息,确定涉及继承的类中父类的方法与子类的方法之间的调用关系,之后根据类与实现相关的信息,确定接口调用实现类的方法的调用关系,最后输出父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系。该技术方案中,根据接口与类之间的继承与实现关系,构建接口与实现类之间,子类与父类之间的实现/继承关系树,结合各接口与类中实现的方法信息,获得未包含在方法调用指令中的接口到实现类、父类到子类、子类到父类的方法调用关系。最终能够通过代码静态分析的方式,不需要执行代码,就能获取代码实际运行时涉及继承与实现的方法调用关系。使得获取到的方法调用关系与代码实际运行时更接近,结果更准确。
在上述实施例的基础上,图3为本申请实施例提供的代码处理方法的流程示意图二,如图3所示,上述步骤22中的对jar包进行预处理,得到jar包中涉及继承的类名和类与实现相关的信息可以包括如下步骤:
步骤31、获取jar包中第一class文件,该第一class文件为jar包中类型为类的class文件。
在该实施例中,类与实现相关的信息可以是在涉及继承的类中、类中实现接口的方法、以及接口中被类实现的方法。
在本步骤中,主要为了获取类中实现接口的方法,需要对jar包中类型为类的class文件进行处理,即第一class文件。
可选的,针对上述确定出的每个jar包,遍历jar包中的各个class文件,找出类型为类的class文件。
步骤32、获取第一class文件中类的接口名列表,并将类中实现接口的方法记载至类实现的接口及类的方法信息映射结构中。
在本步骤中,针对第一class文件中涉及的每个类,获取当前类实现的接口名列表,根据这些接口的方法信息,获取当前类中可能是实现接口中的方法列表,并将实现接口的方法记载至类实现的接口及类的方法信息映射结构中。
可选的,类中实现接口的方法,可以是满足非<init>、非<clinit>、公共、非抽象、非静态方法。
其中,该映射结构可以是一种Map,进而,将实现接口的方法记载至类实现的接口及类的方法信息映射结构中:向“类实现的接口及类的方法信息Map”写入以下数据:Key为当前类的类名,Value为以上获取的当前类实现的接口名列表,以及当前类中可能是实现接口中的方法列表。
步骤33、获取第一class文件中类的父类的类名,当类的父类不属于JDK中的类时,将类的类名和类的父类的类名作为涉及继承的类名,记载至涉及继承的类名集合中。
可选的,在处理第一class文件中当前类时,可以获取当前类的父类类名,若父类不属于JDK中的类,则将当前类名及父类类名添加至“涉及继承的类名集合Set”中。
步骤34、获取jar包中第二class文件,该第二class文件为jar包中类型为接口的class文件。
在本步骤中,主要为了获取接口中被类实现的方法,则需要对jar包中类型为接口的class文件进行处理,即第二class文件。
可选的,针对上述确定出的每个jar包,遍历jar包中的各个class文件,找出类型为接口的class文件。
步骤35、获取第二class文件中接口被类实现的方法列表,并将方法列表中接口中被类实现的方法记载至接口中的方法信息映射结构中。
在本步骤中,获取当前接口中可以被类实现的方法列表,向“接口中的方法信息Map”写入以下数据:Key为当前接口的类名,Value为以上获取的当前接口中可以被类实现的方法列表。
其中,接口中可以被类实现的方法可以是抽象方法。
本申请实施例提供的代码处理方法,获取jar包中第一class文件,该第一class文件为jar包中类型为类的class文件,并获取第一class文件中类的接口名列表,并将类中实现接口的方法记载至类实现的接口及类的方法信息映射结构中,之后获取第一class文件中类的父类的类名,当类的父类不属于Java开发工具包中的类时,将类的类名和类的父类的类名作为涉及继承的类名,记载至涉及继承的类名Set中,再获取jar包中第二class文件,该第二class文件为jar包中类型为接口的class文件,最后获取第二class文件中接口被类实现的方法列表,并将方法列表中接口中被类实现的方法记载至接口中的方法信息映射结构中。该技术方案中,基于class文件的类型不同,对各个class文件进行不同的处理,以得到jar包中涉及继承的类名和类与实现相关的信息,为得到后续接口调用实现类的方法的调用关系提供了基础。
在上述实施例的基础上,图4为本申请实施例提供的代码处理方法的流程示意图三,如图4所示,上述步骤22中的对jar包进行预处理,得到类与继承相关的信息可以包括如下步骤:
步骤41、获取第一class文件中类的父类,若类的父类不在JDK中,将类的类名、类的父类的类名记载至父类的子类类名映射结构中。
在该实施例中,类与继承相关的信息可以是涉及继承的类中,父类对应的子类、子类的父类信息、父类中可被子类重载的方法、子类中可能是重载了父类的方法等信息。
在本步骤中,针对第一class文件中每个类,获取当前类的父类,若父类不在JDK中,则修改“父类的子类类名映射结构”的数据,对于Key为当前父类类名的条目,向其Value即子类类名列表中增加当前类的类名。
步骤42、获取第一class文件中类的方法中涉及重载的方法,将类的类名、类的父类的类名、涉及继承重载的方法记载至涉及继承的类的父类及方法信息映射结构中。
在本步骤中,获取当前类的方法,获得可能涉及重载的方法名称,即满足非<init>、非<clinit>、非静态、抽象或公共或受保护的方法,并获取对应方法的属性,包括是否为抽象/公共/受保护方法。
进而,向“涉及继承的类的父类及方法信息Map”插入数据,Key为当前类的类名,Value中包含了当前类父类类名、可能涉及继承重载的方法。
步骤43、将父类的子类类名映射结构和涉及继承的类的父类及方法信息映射结构中的信息作为类与继承相关的信息。
在本步骤中,使用父类的子类类名映射结构和涉及继承的类的父类及方法信息映射结构,将其中的信息作为类与继承相关的信息。
即将涉及继承的类中,父类对应的子类、子类的父类信息、父类中可被子类重载的方法、子类中可能是重载了父类的方法等信息作为类与继承相关的信息。
本申请实施例提供的代码处理方法,通过获取第一class文件中类的父类,若类的父类不在Java开发工具包,则将类的类名、类的父类的类名记载至父类的子类类名映射结构中,并获取第一class文件中类的方法中涉及重载的方法,将类的类名、类的父类的类名、涉及继承重载的方法记载至涉及继承的类的父类及方法信息映射结构中,之后将父类的子类类名映射结构和涉及继承的类的父类及方法信息映射结构中的信息作为类与继承相关的信息。该技术方案中,对类型为类的class文件进行预处理之后,获取父类对应的子类列表、子类的父类信息、父类中可被子类重载的方法、子类中可能是重载了父类的方法等信息,为后续补充继承与实现相关方法调用关系提供了基础。
在上述实施例的基础上,图5A为本申请实施例提供的代码处理方法的流程示意图四,如图5A所示,上述步骤23可以包括如下步骤:
步骤51、根据父类及方法信息映射结构,确定类的顶层父类。
应理解:顶层父类是指一个类的最上层的父类,例如AA的父类为BB,BB的父类为CC,CC的父类为Java开发工具包中的Object,则认为AA的顶层父类为CC。
在本步骤中,由于Java不支持多继承,每个类只能继承一个类,因此每个类有且仅有一个父类。将Java项目中以JDK中的类作为父类的类称为顶层父类,顶层父类不会以Java项目中的其他类作为父类,Java项目中的其他类都会以某个顶层父类,或顶层父类的直接或间接子类作为父类。
Java项目中的每个顶层父类,或其直接或间接子类可以没有子类,也可以有一个或多个子类。顶层父类与其子类,及间接子类之间的关系会形成一个树形结构,如图5B所示(图5B为本申请实施例提供的父类-子类结构树示意图一):
即,顶层父类下有父类1和父类2;父类1下有子类1.1和子类1.2;父类2下父类2.1;父类2.1下有子类2.1.1和子类2.1.2。
在补充父类方法与子类方法之间的调用关系时,首先需要查找所有的顶层父类,再依次对每个顶层父类及其子类进行处理,补充方法调用关系。
因此,在本步骤中,Java项目中可以存在任意数量的顶层父类,从某个类开始,查找其顶层父类的过程如下:1、循环执行以下处理;2、获取当前类的父类;3、判断获取到的父类是否存在;4、假如获取到的父类存在,则继续处理该父类;5、获取到的父类不存在,则当前类就是一个顶层父类,结束循环。
即一种可能的实现下,图5C为本申请实施例提供的父类-子类结构树示意图二,如图5C所示:
针对子类1.1,首先确定其父类1,再确定父类1的父类L,之后确定父类L的父类是否存在,不存在时,则顶层父类即为父类L;针对子类1.2,首先确定其父类1,再确定父类1的父类L,之后确定父类L的父类,因其不存在,则顶层父类即为父类L;针对子类2.1.1,首先确定其父类2.1,再确定父类2.1的父类2,之后确定父类2的父类为父类L,再确定父类L的父类,因其不存在,则顶层父类即为父类L;针对子类2.1.2,首先确定其父类2.1,再确定父类2.1的父类2,之后确定父类2的父类为父类L,再确定父类L的父类,因其不存在,则顶层父类即为父类L。
在此过程中,遍历“父类及方法信息Map”中的每一个条目,从当前处理的条目的Value中获取当前类的父类;若当前类的父类在JDK中,则当前类为一个顶层父类;从当前条目的Key获取当前类的类名,并将当前类的类名记录为属于顶层父类。
步骤52、从顶层父类开始,逐层确定出各对父类与子类。
在本步骤中,从顶层父类开始处理,通过深度优先的方式对顶层父类及其子类的树形结构进行遍历,即从顶层父类开始,逐层确定出各对父类与子类。
具体的,将顶层父类作为当前处理的节点,获取当前节点还未处理过的一个子类(从序号小的子类开始获取),假如有获取到当前节点的一个子类,则补充相邻的父类方法与子类方法之间的调用关系;再将子类作为当前节点,继续进行处理;假如未获取到当前节点的一个子类,则回溯到当前节点的父类,假如父类是顶层父类,且顶层父类的所有子类都已处理完毕,则结束处理;其他情况下,将父类作为当前节点,继续进行以上处理。
即一种可能的实现下,图5D为本申请实施例提供的父类-子类结构树示意图三,如图5D所示:
从顶层父类L开始,向下确定出顶层父类L的子类即父类1和父类2;父类1的子类即子类1.1和子类1.2;父类2的子类即父类2.1;父类2.1的子类是子类2.1.1和子类2.1.2。
在遍历一个顶层父类的所有子类时,需要使用“父类的子类类名映射结构”中父类与子类的信息,以上Map中保存的Key为当前父类类名,Value为父类的子类类名List,具体的,图5E为本申请实施例提供的父类的子类类名映射结构示意图,如图5E所示:
父类对应的子类信息如下:Key集合下:父类a类名、父类b类名、…父类n类名;Value集合下:父类a类名对应子类a1类名、子类a2类名、…子类an类名;父类b类名对应子类b1类名、子类b2类名、…子类bn类名;父类n类名对应子类n1类名、子类n2类名、…子类nn类名。
为了准确高效地遍历一个顶层父类的所有子类,需要记录已经处理的节点信息,以及当前正在处理的节点信息,使用“顶层父类节点信息List”变量保存以上信息,List中的每个元素代表了对一个节点的处理信息,List元素中包含对应的父类类名,及处理到的子类类名的下标。
需要记录“遍历顶层父类节点信息List”中当前正在处理的元素下标:在初始时,当前正在处理的元素下标为0,即指向“遍历顶层父类节点信息List”中的第一个元素;获取到父类的一个子类时,将正在处理的元素下标向增大的方向移动一次;从子类回溯到父类时,将正在处理的元素下标向减小的方向移动一次。即“遍历顶层父类节点信息List”中,小于当前正在处理的元素下标的元素都是已经处理过的;大于当前正在处理的元素下标的元素,是后续可能会处理的。
“顶层父类节点信息List”及当前正在处理的元素下标的使用如下图5F所示(图5F为本申请实施例提供的父类与子类处理示意图)。
步骤53、从涉及继承的类的父类及方法信息映射结构中确定出每对父类与子类中父类对应的第一全部方法信息、以及子类对应的第二全部方法信息。
在本步骤中,在遍历一个顶层父类的子类时,找到一对相邻的父类与子类之后,需要补充相邻的父类与子类之间的方法调用关系。
即需要从“涉及继承的类的父类及方法信息Map”中,根据父类类名获取父类的全部方法信息,即第一全部方法信息;从“涉及继承的类的父类及方法信息Map”中,根据子类类名获取子类的全部方法信息,即第二全部方法信息。
步骤54、根据所有第一全部方法信息和所有第二全部方法信息,确定父类的方法与子类的方法之间的调用关系。
可选的,该步骤54的实现可以有以下步骤:
第1步、针对每对父类与子类,确定父类中各个方法的类型。
可选的,遍历父类的每个方法,确定父类中各个方法的类型。
例如,当前方法为抽象方法、或者是非抽象的公共或受保护方法。
第2步、若父类中方法的类型为抽象方法,添加父类的方法调用子类的同名且参数相同方法的调用关系。
例如,父类的当前方法为抽象方法,则添加父类的当前方法调用子类的同名且参数相同方法的调用关系。
第3步、若父类中方法的类型为非抽象的公共或受保护方法,且子类中不存在对应方法,则将父类的方法添加到子类的方法中,并添加子类的同名且参数相同方法调用父类的方法的调用关系。
例如,父类的当前方法为非抽象的公共或受保护方法,且子类中不存在当前方法,则将父类的当前方法添加到子类的方法中,并添加子类的同名且参数相同方法调用父类的当前方法的调用关系。
本申请实施例提供的代码处理方法,通过根据父类及方法信息映射结构,确定类的顶层父类,并从顶层父类开始,逐层确定出各对父类与子类,之后从涉及继承的类的父类及方法信息映射结构中确定出每对父类与子类中父类对应的第一全部方法信息、以及子类对应的第二全部方法信息,最后根据所有第一全部方法信息和所有第二全部方法信息,确定父类的方法与子类的方法之间的调用关系。该技术方案中,从父类与其子类对应的方法信息出发,更加准确的确定出了父类的方法与子类的方法之间的调用关系。
在上述实施例的基础上,图6为本申请实施例提供的代码处理方法的流程示意图五,如图6所示,上述步骤24可以包括如下步骤:
步骤61、从类实现的接口及类的方法信息映射结构中确定出类实现的全部接口。
在本步骤中,遍历“类实现的接口及类的方法信息Map”中的每个类的相关信息,从中确定出当前类实现的全部接口列表,遍历该列表可得到类实现的全部接口。
步骤62、从接口中的方法信息映射结构的方法列表中确定出各个接口定义的方法列表。
在本步骤中,根据当前处理的接口类名,从“接口中的方法信息Map”中获取当前接口中定义的方法列表。
步骤63、针对方法列表中在接口中存在同名且参数相同的方法,添加至接口方法调用实现类同名且参数相同的方法的调用关系。
在本步骤中,遍历当前处理类中的全部方法列表,对于当前类的当前方法在当前接口中存在同名且参数相同的方法,说明是类实现了对应接口的方法,添加当前接口方法调用当前类当前方法的调用关系。
本申请实施例提供的代码处理方法,通过从类实现的接口及类的方法信息映射结构中确定出类实现的全部接口,并从接口中的方法信息映射结构的方法列表中确定出各个接口定义的方法列表,之后针对方法列表中各个方法在接口中存在同名且参数相同的方法,添加至接口方法调用实现类的方法的调用关系,从而确定出接口调用实现类的方法的调用关系。
下述为上述实施例中涉及的方法的一些实现的示例:
示例一:图7为本申请实施例提供的代码处理方法总流程示意图,如图7所示,总方法的流程可以包括如下步骤:
第1步、获取程序中执行参数中指定的需要处理的jar包,支持指定多个jar包一次处理;
第2步、遍历所有指定的jar包,对jar包中的class文件进行第一次预处理,用于获得涉及继承的类名,及类与实现相关的信息;
第3步、遍历所有的jar包,对jar包中的class文件进行第二次预处理,用于获得类与继承相关的信息;包括子类指向父类,或者子接口指向父接口等;
第4步、遍历所有的jar包,在处理每个jar包时,遍历其中的class文件,并对class文件进行后续的处理;
第5步、在处理class文件时,遍历当前类中的方法,并对每个方法进行处理;
第6步、在处理类中的方法时,获取当前方法对其他方法的调用关系;
第7步、在获取了所有方法之间的调用关系后,补充父类方法与子类方法之间的调用关系;
第8步、在获取了所有方法之间的调用关系后,补充接口调用实现类方法的调用关系;
第9步、将获取到的全部方法调用关系输出到结果文件中。
示例二:图8为本申请实施例提供的涉及继承的类名、及类与实现相关的信息的确定方式流程图,如图8所示,该确定方式可以包括如下步骤:
第1步、遍历jar包中的class文件;
第2步、判断当前class文件对应的类型,若为类,则执行第3步;若为接口,则执行第8步;
第3步、获取当前类实现的接口名列表;
第4步、在接口名列表中获取当前类中可能是实现接口中的方法列表,找到满足非<init>、非<clinit>、公共、非抽象、非静态方法;
第5步、向“类实现的接口及类的方法信息Map”写入数据;
具体为:Key为当前类的类名,Value为以上获取的当前类实现的接口名列表,以及当前类中可能是实现接口中的方法列表。
第6步、判断当前类的父类类名是否属于JDK中的类,若父类不属于JDK中的类,则执行第7步,若属于JDK中的类,执行第10步;
第7步、将当前类名及父类类名添加至“涉及继承的类名Set”中,之后执行第10步;
第8步、获取当前接口中可以被类实现的方法列表,即抽象方法;
第9步、向“接口中的方法信息Map”写入数据;
具体为:Key为当前接口的类名,Value为以上获取的当前接口中可以被类实现的方法列表;
第10步、结束。
示例三:图9为本申请实施例提供的类与继承相关的信息的确定方式流程图,如图9所示,该确定方式可以包括如下步骤:
第1步、遍历jar包中的class文件;
第2步、判断当前class文件对应的类型,若为类,则执行第3步;否则执行第8步;
第3步、判断当前类是否在涉及继承的类名Set中,是则执行第4步;否则执行第8步;
第4步、获取当前类的父类;
第5步、判断父类是否位于JDK中,若否执行第6步,若是,执行第7步;
第6步、修改“父类的子类类名Map(即映射结构)”,Key为当前父类类名的条目,向其Value即子类类名列表中增加当前类的类名;
第7步、获取当前类的方法,获得可能涉及重载的方法名称,即满足非<init>、非<clinit>、非静态、抽象或公共或受保护的方法,并获取对应方法的属性,包括是否为抽象/公共/受保护方法;向“涉及继承的类的父类及方法信息Map”插入数据,Key为当前类的类名,Value中包含了当前类父类类名、可能涉及继承重载的方法;
第8步、结束。
示例四:图10为本申请实施例提供的父类方法与子类方法之间的调用关系的确定方式流程图,如图10所示,该确定方式可以包括如下步骤:
第1步、从“涉及继承的类的父类及方法信息Map”中,根据父类类名获取父类的全部方法信息、以及根据子类类名获取子类的全部方法信息;
第2步、遍历父类的每个方法,判断父类的当前方法是否为抽象方法,若否,执行第3步;若是,执行第8步;
第3步、判断父类的当前方法是否为非抽象公共或受保护方法,若是,执行第4步;若否,执行第7步;
第4步、判断子类是否存在父类的当前方法,若是,执行第5步;若否,执行第7步;
第5步、将父类的方法添加至子类的方法中;
第6步、添加子类的同名且参数相同方法调用父类的当前方法的调用关系;
第7步、结束
第8步、添加父类的当前方法调用子类的同名且参数相同方法的调用关系,之后执行第3步。
示例五:图11为本申请实施例提供的接口调用实现类的方法的调用关系的确定方式流程图,如图11所示,该确定方式可以包括如下步骤:
第1步、遍历“类实现的接口及类的方法信息Map”中的每个类的相关信息;
第2步、遍历当前处理类实现的全部接口列表;
第3步、根据当前处理的接口类名,从“接口中的方法信息Map”中获取当前接口中定义的方法列表;
第4步、遍历当前处理类中的全部方法列表;
第5步、对于当前类的当前方法在当前接口中存在同名且参数相同的方法,说明是类实现了对应接口的方法,添加当前接口方法调用当前类当前方法的调用关系;
第6步、结束。
在以上示例中,在Java项目特别是使用Spring框架的项目中,在定义对象时使用接口或父类类型,而不是对应的实现类或子类类型,是非常普通的使用方式,这是为了代码更加灵活,便于维护。由于原有的项目仅根据方法调用指令的信息获取各个方法之间的调用关系,以上的使用方式会导致涉及继承与实现的场景中,仅能获取到调用接口或父类方法的调用关系,无法关联到对应的实现类及子类的方法,原有的项目获取方法调用关系时会出现很多丢失。本申请实施例所使用的方案,对代码的实际运行情况进行了模拟,结合方法调用指令之外的信息,对方法调用关系进行补充。根据接口与类之间的继承与实现关系,构建接口与实现类之间,子类与父类之间的实现/继承关系树,结合各接口与类中实现的方法信息,获得未包含在方法调用指令中的接口到实现类、父类到子类、子类到父类的方法调用关系。最终能够通过代码静态分析的方式,不需要执行代码,就能获取代码实际运行时涉及继承与实现的方法调用关系。使得获取到的方法调用关系与代码实际运行时更接近,结果更准确。
下述为本申请装置实施例,可以用于执行本申请方法实施例。对于本申请装置实施例中未披露的细节,请参照本申请方法实施例。
图12为本申请实施例提供的代码处理装置实施例的结构示意图。如图12所示,该装置包括:
获取模块121,用于获取应用程序的执行参数涉及的jar包;
处理模块122,用于对jar包进行预处理,得到jar包中涉及继承的类名、类与实现相关的信息、类与继承相关的信息;
第一确定模块123,用于根据涉及继承的类名、类与继承相关的信息,确定涉及继承的类中父类的方法与子类的方法之间的调用关系;
第二确定模块124,用于根据类与实现相关的信息,确定接口调用实现类的方法的调用关系;
输出模块125,用于输出父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系。
在本申请实施例一种可能的设计中,类与实现相关的信息包括:类中实现接口的方法、以及接口中被类实现的方法;
相应的,处理模块122对jar包进行预处理,得到jar包中涉及继承的类名和类与实现相关的信息,具体用于:
获取jar包中第一class文件,第一class文件为jar包中类型为类的class文件;
获取第一class文件中类的接口名列表,并将类中实现接口的方法记载至类实现的接口及类的方法信息映射结构中;
获取第一class文件中类的父类的类名,当类的父类不属于Java开发工具包中的类时,将类的类名和类的父类的类名作为涉及继承的类名,记载至涉及继承的类名Set中;
获取jar包中第二class文件,第二class文件为jar包中类型为接口的class文件;
获取第二class文件中接口被类实现的方法列表,并将方法列表中接口中被类实现的方法记载至接口中的方法信息映射结构中。
可选的,处理模块122对jar包进行预处理,得到类与继承相关的信息,具体用于:
获取第一class文件中类的父类,若类的父类不在Java开发工具包,将类的类名、类的父类的类名记载至父类的子类类名映射结构中;
获取第一class文件中类的方法中涉及重载的方法,将类的类名、类的父类的类名、涉及继承重载的方法记载至涉及继承的类的父类及方法信息映射结构中;
将父类的子类类名映射结构和涉及继承的类的父类及方法信息映射结构中的信息作为类与继承相关的信息。
可选的,第一确定模块123,具体用于:
根据父类及方法信息映射结构,确定类的顶层父类;
从顶层父类开始,逐层确定出各对父类与子类;
从涉及继承的类的父类及方法信息映射结构中确定出每对父类与子类中父类对应的第一全部方法信息、以及子类对应的第二全部方法信息;
根据所有第一全部方法信息和所有第二全部方法信息,确定父类的方法与子类的方法之间的调用关系。
可选的,第一确定模块123,根据所有第一全部方法信息和所有第二全部方法信息,确定父类的方法与子类的方法之间的调用关系,具体用于:
针对每对父类与子类,确定父类中各个方法的类型;
若父类中方法的类型为抽象方法,添加父类的方法调用子类的同名且参数相同方法的调用关系;
若父类中方法的类型为非抽象的公共或受保护方法,且子类中不存在方法,则将父类的方法添加到子类的方法中,并添加子类的同名且参数相同方法调用父类的方法的调用关系。
可选的,第二确定模块124,具体用于:
从类实现的接口及类的方法信息映射结构中确定出类实现的全部接口;
从接口中的方法信息映射结构的方法列表中确定出各个接口定义的方法列表;
针对方法列表中各个方法在接口中存在同名且参数相同的方法,添加至接口方法调用实现类的方法的调用关系。
在本申请实施例另一种可能的设计中,第三确定模块,用于:
若涉及继承的类中当前方法对应的目标指令为方法调用指令,根据方法调用指令的属性,从常量池中获取被目标指令调用的方法名称、被目标指令调用的对象类型、被目标指令调用的每个参数的类型,以得到当前方法与其他方法的调用关系;
相应的,在根据类与实现相关的信息,确定接口调用实现类的方法的调用关系之后,输出模块125,还用于:
输出当前方法与其他方法的调用关系。
可选的,输出模块125,具体用于:
将父类的方法与子类的方法之间的调用关系,和接口调用实现类的方法的调用关系输出至结果文件;
相应的,输出模块125,还具体用于:
将当前方法与其他方法的调用关系输出至结果文件。
本申请实施例提供的装置,可用于执行上述任一实施例中的代码处理确定方法,其实现原理和技术效果类似,在此不再赘述。
需要说明的是,应理解以上装置的各个模块的划分仅仅是一种逻辑功能的划分,实际实现时可以全部或部分集成到一个物理实体上,也可以物理上分开。且这些模块可以全部以软件通过处理元件调用的形式实现;也可以全部以硬件的形式实现;还可以部分模块通过处理元件调用软件的形式实现,部分模块通过硬件的形式实现。此外,这些模块全部或部分可以集成在一起,也可以独立实现。这里所述的处理元件可以是一种集成电路,具有信号的处理能力。在实现过程中,上述方法的各步骤或以上各个模块可以通过处理器元件中的硬件的集成逻辑电路或者软件形式的指令完成。
图13为本申请实施例提供的电子设备的结构示意图,如图13所示,该电子设备可以包括:处理器131、存储器132及存储在所述存储器132上并可在处理器131上运行的计算机执行指令,所述处理器131执行所述计算机程序指令时实现前述任一实施例提供的方法。
可选的,该电子设备的上述各个器件之间可以通过系统总线连接。
存储器132可以是单独的存储单元,也可以是集成在处理器131中的存储单元。处理器131的数量为一个或者多个。
应理解,处理器131可以是中央处理单元(Central Processing Unit,CPU),还可以是其他通用处理器131、数字信号处理器131(Digital Signal Processor,DSP)、专用集成电路(Application Specific Integrated Circuit,ASIC)等。通用处理器131可以是微处理器131或者该处理器131也可以是任何常规的处理器131等。结合本申请所公开的方法的步骤可以直接体现为硬件处理器131执行完成,或者用处理器131中的硬件及软件模块组合执行完成。
系统总线可以是外设部件互连标准(peripheral component interconnect,PCI)总线或扩展工业标准结构(extended industry standard architecture,EISA)总线等。系统总线可以分为地址总线、数据总线、控制总线等。为便于表示,图中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。存储器132可能包括随机存取存储器132(random access memory,RAM),也可能还包括非易失性存储器132(non-volatile memory,NVM),例如至少一个磁盘存储器132。
实现上述各方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成。前述的程序可以存储于一可读取存储器132中。该程序在执行时,执行包括上述各方法实施例的步骤;而前述的存储器132(存储介质)包括:只读存储器132(read-only memory,ROM)、RAM、快闪存储器132、硬盘、固态硬盘、磁带(英文:magnetic tape)、软盘(英文:floppydisk)、光盘(英文:optical disc)及其任意组合。
本申请实施例提供的电子设备,可用于执行上述任一方法实施例提供的方法,其实现原理和技术效果类似,在此不再赘述。
本申请实施例提供一种计算机可读存储介质,该计算机可读存储介质中存储有计算机指令,当该计算机指令在计算机上运行时,使得计算机执行上述方法。
上述的计算机可读存储介质,上述可读存储介质可以是由任何类型的易失性或非易失性存储设备或者它们的组合实现,如静态随机存取存储器,电可擦除可编程只读存储器,可擦除可编程只读存储器,可编程只读存储器,只读存储器,磁存储器,快闪存储器,磁盘或光盘。可读存储介质可以是通用或专用计算机能够存取的任何可用介质。
可选的,将可读存储介质耦合至处理器,从而使处理器能够从该可读存储介质读取信息,且可向该可读存储介质写入信息。当然,可读存储介质也可以是处理器的组成部分。处理器和可读存储介质可以位于专用集成电路(Application Specific IntegratedCircuits,ASIC)中。当然,处理器和可读存储介质也可以作为分立组件存在于设备中。
本申请实施例还提供一种计算机程序产品,该计算机程序产品包括计算机程序,该计算机程序存储在计算机可读存储介质中,至少一个处理器可以从该计算机可读存储介质中读取该计算机程序,所述至少一个处理器执行所述计算机程序时可实现上述方法。
应当理解的是,本公开并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本公开的范围仅由所附的权利要求书来限制。
Claims (11)
1.一种代码处理方法,其特征在于,包括:
获取应用程序的执行参数涉及的jar包;
对所述jar包进行预处理,得到所述jar包中涉及继承的类名、类与实现相关的信息、所述类与继承相关的信息;
根据所述涉及继承的类名、所述类与继承相关的信息,确定所述涉及继承的类中父类的方法与子类的方法之间的调用关系;
根据所述类与实现相关的信息,确定接口调用实现类的方法的调用关系;
输出所述父类的方法与子类的方法之间的调用关系,和所述接口调用实现类的方法的调用关系。
2.根据权利要求1所述的方法,其特征在于,所述类与实现相关的信息包括:所述类中实现接口的方法、以及所述接口中被类实现的方法;
相应的,对所述jar包进行预处理,得到所述jar包中涉及继承的类名和类与实现相关的信息,包括:
获取所述jar包中第一class文件,所述第一class文件为所述jar包中类型为类的class文件;
获取所述第一class文件中类的接口名列表,并将所述接口名列表中所述类中实现接口的方法记载至类实现的接口及类的方法信息映射结构中;
获取所述第一class文件中类的父类的类名,当所述类的父类不属于Java开发工具包中的类时,将所述类的类名和所述类的父类的类名作为所述涉及继承的类名,记载至涉及继承的类名集合中;
获取所述jar包中第二class文件,所述第二class文件为所述jar包中类型为接口的class文件;
获取所述第二class文件中接口被类实现的方法列表,并将所述方法列表中所述接口中被类实现的方法记载至接口中的方法信息映射结构中。
3.根据权利要求2所述的方法,其特征在于,对所述jar包进行预处理,得到所述类与继承相关的信息,包括:
获取所述第一class文件中类的父类,若所述类的父类不在Java开发工具包中,则将所述类的类名、及所述类的父类的类名记载至父类的子类类名映射结构中;
获取所述第一class文件中类的方法中涉及重载的方法,将所述类的类名、所述类的父类的类名、涉及继承重载的方法记载至涉及继承的类的父类及方法信息映射结构中;
将所述父类的子类类名映射结构和所述涉及继承的类的父类及方法信息映射结构中的信息作为所述类与继承相关的信息。
4.根据权利要求3所述的方法,其特征在于,所述根据所述涉及继承的类名、所述类与继承相关的信息,确定所述涉及继承的类中父类的方法与子类的方法之间的调用关系,包括:
根据所述父类及方法信息映射结构,确定所述类的顶层父类;
从所述顶层父类指向所述顶层父类的子类开始,逐层确定出各对父类与子类;
从所述涉及继承的类的父类及方法信息映射结构中确定出每对父类与子类中父类对应的第一全部方法信息、以及子类对应的第二全部方法信息;
根据所有所述第一全部方法信息和所有所述第二全部方法信息,确定所述父类的方法与子类的方法之间的调用关系。
5.根据权利要求4所述的方法,其特征在于,所述根据所有所述第一全部方法信息和所有所述第二全部方法信息,确定所述父类的方法与子类的方法之间的调用关系,包括:
针对每对父类与子类,确定所述父类中各个方法的类型;
若所述父类中方法的类型为抽象方法,则添加所述父类的方法调用所述子类的同名且参数相同方法的调用关系;
若所述父类中方法的类型为非抽象的公共或受保护方法,且所述子类中不存在所述方法,则将所述父类的方法添加到所述子类的方法中,并添加所述子类的同名且参数相同方法调用所述父类的方法的调用关系。
6.根据权利要求4所述的方法,其特征在于,所述根据所述类与实现相关的信息,确定接口调用实现类的方法的调用关系,包括:
从所述类实现的接口及类的方法信息映射结构中确定出所述类实现的全部接口;
从所述接口中的方法信息映射结构的所述方法列表中确定出各个接口定义的方法列表;
针对所述方法列表中各个方法在接口中存在同名且参数相同的方法,添加所述接口方法调用实现类的方法的调用关系。
7.根据权利要求1-6任一项所述的方法,其特征在于,在所述根据所述涉及继承的类名、所述类与继承相关的信息,确定所述涉及继承的类中父类的方法与子类的方法之间的调用关系之前,所述方法还包括:
若所述涉及继承的类中当前方法对应的目标指令为方法调用指令,根据方法调用指令的属性,从常量池中获取被所述目标指令调用的方法名称、被所述目标指令调用的对象类型、被所述目标指令调用的每个参数的类型,以得到所述当前方法与其他方法的调用关系;
相应的,在所述根据所述类与实现相关的信息,确定接口调用实现类的方法的调用关系之后,所述方法还包括:
输出所述当前方法与其他方法的调用关系。
8.根据权利要求7所述的方法,其特征在于,所述输出所述父类的方法与子类的方法之间的调用关系,和所述接口调用实现类的方法的调用关系,包括:
将所述父类的方法与子类的方法之间的调用关系和所述接口调用实现类的方法的调用关系输出至结果文件中;
相应的,所述输出所述当前方法与其他方法的调用关系,包括:
将所述当前方法与其他方法的调用关系输出至所述结果文件中。
9.一种代码处理装置,其特征在于,包括:
获取模块,用于获取应用程序的执行参数涉及的jar包;
处理模块,用于对所述jar包进行预处理,得到所述jar包中涉及继承的类名、类与实现相关的信息、所述类与继承相关的信息;
第一确定模块,用于根据所述涉及继承的类名、所述类与继承相关的信息,确定所述涉及继承的类中父类的方法与子类的方法之间的调用关系;
第二确定模块,用于根据所述类与实现相关的信息,确定接口调用实现类的方法的调用关系;
输出模块,用于输出所述父类的方法与子类的方法之间的调用关系,和所述接口调用实现类的方法的调用关系。
10.一种电子设备,其特征在于,包括:处理器,以及与所述处理器通信连接的存储器;
所述存储器存储计算机执行指令;
所述处理器执行所述存储器存储的计算机执行指令,以实现如上述权利要求1至8任一项所述的方法。
11.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质中存储有计算机执行指令,所述计算机执行指令被处理器执行时用于实现如上述权利要求1至8任一项所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202310152286.4A CN116048731A (zh) | 2023-02-08 | 2023-02-08 | 代码处理方法、装置、电子设备及存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202310152286.4A CN116048731A (zh) | 2023-02-08 | 2023-02-08 | 代码处理方法、装置、电子设备及存储介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN116048731A true CN116048731A (zh) | 2023-05-02 |
Family
ID=86131444
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202310152286.4A Pending CN116048731A (zh) | 2023-02-08 | 2023-02-08 | 代码处理方法、装置、电子设备及存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN116048731A (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117008884A (zh) * | 2023-07-06 | 2023-11-07 | 广州三七极耀网络科技有限公司 | 游戏开发中的逻辑类处理方法、装置、设备及存储介质 |
CN118503971A (zh) * | 2024-07-18 | 2024-08-16 | 杭州新中大科技股份有限公司 | 调用关系分析方法、装置、电子设备和存储介质 |
-
2023
- 2023-02-08 CN CN202310152286.4A patent/CN116048731A/zh active Pending
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117008884A (zh) * | 2023-07-06 | 2023-11-07 | 广州三七极耀网络科技有限公司 | 游戏开发中的逻辑类处理方法、装置、设备及存储介质 |
CN117008884B (zh) * | 2023-07-06 | 2024-05-17 | 广州三七极耀网络科技有限公司 | 游戏开发中的逻辑类处理方法、装置、设备及存储介质 |
CN118503971A (zh) * | 2024-07-18 | 2024-08-16 | 杭州新中大科技股份有限公司 | 调用关系分析方法、装置、电子设备和存储介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110162296B (zh) | 应用程序编程接口文档的生成方法、装置及终端设备 | |
US11366643B2 (en) | Generating dynamic modular proxies | |
US8458681B1 (en) | Method and system for optimizing the object code of a program | |
US10158647B2 (en) | Permissive access control for modular reflection | |
US7627594B2 (en) | Runtime support for nullable types | |
US20140325534A1 (en) | Runtime system | |
CN110007920B (zh) | 一种获取代码依赖关系的方法、装置及电子设备 | |
US10459708B2 (en) | Composing a module system and a non-module system | |
US8429632B1 (en) | Method and system for debugging merged functions within a program | |
US10078497B2 (en) | Bridging a module system and a non-module system | |
CN110069259B (zh) | 基于idl文件的解析方法、装置、电子设备和存储介质 | |
US20090319554A1 (en) | Unified metadata for external components | |
AU4505801A (en) | Language subset validation | |
US20170286255A1 (en) | Generating verification metadata and verifying a runtime type based on verification metadata | |
US20220300264A1 (en) | Implementing optional specialization when compiling code | |
CN115617353B (zh) | 基于ksp生成描述文件的方法及快速插桩的gradle编译系统 | |
US10983771B1 (en) | Quality checking inferred types in a set of code | |
CN116048731A (zh) | 代码处理方法、装置、电子设备及存储介质 | |
JP4806158B2 (ja) | マークアップ内でサブクラスを宣言的に定義し、使用するためのシステムおよび方法 | |
US10387142B2 (en) | Using annotation processors defined by modules with annotation processors defined by non-module code | |
US8949103B2 (en) | Program code simulator | |
CN111475150A (zh) | 一种跨语言绑定方法、装置、设备及存储介质 | |
US20210036944A1 (en) | Ranking service implementations for a service interface | |
CN117149209A (zh) | 一种代码增量编译方法、装置、计算机设备及存储介质 | |
CN113971019B (zh) | 数据类型创建方法、装置、服务器及介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication |