对于这样的java代码
pubic interface TestInterface {
int foo();
int foo1();
}
pubic interface TestClass implement TestInterface{
public int foo(){
int a = 0;
reurn a;
}
public int foo1(){
int a = 1;
reurn a;
}
}
TestInterface i = new TestClass();
i.foo();
javac之后会生成invoke_interface 的字节码.相关的实现位于templateTable::invokeInterface(int)生成的代码中.
java对象的的内存布局.
首先,变量i指向的内存布局是这样的.
[oopDesc][长度与类相关的内存区域]
oopDesc 包含2个成员, markWord和 klass.其中klass在未启用指针压缩时,指向该对象的类信息.
这个"类信息"不是java.lang.Class,而是虚拟机使用的内部数据.
klass指向的内存区域布局,参见(instanceKlass.hpp)
[klassOopDesc][instanceKlass][javaVtable][javaItable][静态成员][oop map]
klassOopDesc继承于oopDesc,添加了方法,但是没有新成员变量,所以内存结构一样.instanceKlass包含大量的类信息.其中,这里需要用到的就有 vtable_length, 其值就是javaVtable的长度.
[javaVtable] ==> vtable_length 个 method指针.
对于这里的例子,应该是以这个顺序
(Object类的方法)================
finalize
equals
toString
hashCode
clone
(TestClass类的方法)==
foo
foo1
java Itable内存布局,首先是该类说实现的所有接口类,以及该接口类的方法的偏移位置.最后以0表示接口类信息结束, 然后尾随的就是所有接口类的每个方法
interface0, offset
interface1, offset
.
.
.
interfacen, offset
0 0
========================
interface0_方法0
interface0_方法1
.
.
.
interface1_方法0
interface1_方法1
.
.
.
在上面的额示例代码里.itable就是
指向TestInterface指针, 偏移量
---
0, 0
|
指向foo方法的指针
<--------------
指向foo1方法的指针
来看看invokeinterface的源码,
首先是和其他方法调用一样.
prepare_invoke()先去缓存找方法, 找不到就解析.连接
重点在这里
lookup_interface_method
movl(scan_temp, Address(recv_klass, instanceKlass::vtable_length_offset() * wordSize));
//scan_temp = (instanceKlass*)(recv_klass+ sizeof(klassOopDesc) )->_vtable_len
lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
//scan_temp = recv_klass + vtable_base + scan_temp * sizeof(vtableEntry); // end of vtable, vtable的后面就是itable了
lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
//recv_klass = recv_klass + itable_index * sizeof(itableMethodEntry) + offset_of(itableMethodEntry, _method) @1
for (int peel = 1; peel >= 0; peel--) {
movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
cmpptr(intf_klass, method_result);
if (peel) {
jccb(Assembler::equal, found_method);
} else {
jccb(Assembler::notEqual, search);
// (invert the test to fall through to found_method...)
}
if (!peel) break;
bind(search);
// Check that the previous entry is non-null. A null entry means that
// the receiver class doesn't implement the interface, and wasn't the
// same as when the caller was compiled.
testptr(method_result, method_result);
jcc(Assembler::zero, L_no_such_interface);
addptr(scan_temp, scan_step);
}
bind(found_method);
//上面的代码简直坑爹展开一下
movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
//method_result = scan_temp->_interface
cmpptr(intf_klass, method_result);
jccb(Assembler::equal, found_method);
//if(intf_klass == method_result)
// goto found_method;
bind(search);
testptr(method_result, method_result);
jcc(Assembler::zero, L_no_such_interface);
//if(method_result == 0)
// goto L_no_such_interface;
addptr(scan_temp, scan_step);
// scan_temp += sizeof(itableOffsetEntry);
movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
//method_result = scan_temp->_interface
cmpptr(intf_klass, method_result);
jccb(Assembler::notEqual, search);
//if(intf_klass != result)
// goto search;
bind(found_method);
// Got a hit.
movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
//scan_temp = ((itableOffsetEntry*)scan_temp)->_offset
movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
//method_result= recv_klass + scan_temp->_offset @2
//@1+@2 ==>
//method_result = ((itableMethodEntry*)(recv_klass + scan_temp->_offset))[itable_index]._method
for (scan = klass->itable(); scan->interface() != NULL; scan += sizeof(itableOffsetEntry)) {
if (scan->interface() == intf) {
result = (klass + scan->offset() + itable_index);
}
}
最后顺便提一句.vtable里是有接口方法的的.
所以类似
引用
TestClass t = new TestClass();//或者是TestClass的子类
t.foo();
这种事走vtable的,具体的javap看一下,他生成的是invokeVirtual
分享到:
相关推荐
Java调用SOAP(Simple Object Access Protocol)接口是Web服务交互中的常见操作,SOAP是一种基于XML的协议,用于在Web上交换结构化的和类型化的信息。本案例主要关注如何使用Java来实现SOAP请求并获取响应,具体我们...
5. **MyXMLRPC源码分析**: - `MyXMLRPC`可能包含了服务端和客户端的示例代码。 - 服务端代码可能包含一个实现XML-RPC接口的类,以及启动XML-RPC服务器的部分。 - 客户端代码可能包含创建XML-RPC客户端,设置...
总结来说,Java调用新浪微博API接口涉及OAuth2.0授权、API接口调用、源码解析和最佳实践等多个方面。了解并熟练掌握这些知识点,可以有效地实现Java应用与微博平台的交互,提供丰富的社交功能。
4. **源码分析**:提供的源码可能是实现与招商银行接口交互的示例代码,或者是实际用于生产环境的代码。通过阅读和理解源码,开发者可以学习如何正确地构造请求,如何处理返回的数据,以及如何处理可能出现的异常...
从给定的文件片段中,我们可以提取出关于Java中Object类和String类的源码分析的知识点。 首先,Object类是Java中所有类的根类。它包含了所有对象共有的方法,是所有类继承结构的最顶层。从文件片段中我们可以看到...
3. **Java调用MATLAB的工程**:这是核心部分,它会使用Java代码通过MATLAB Compiler生成的Java接口调用前面两个MATLAB工程中的功能。 在标签“java matlab 读图片”中,我们可以推断出Java工程的一个主要功能是读取...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛这些方法是在本地对象上执行一样。这个技术极大地简化了构建分布式应用的...
源码分析可以帮助理解如何利用反射进行类的动态加载、方法的调用等。 8. **JVM内部机制**:虽然Java源码不包括JVM本身,但通过阅读和分析使用JVM特性的代码,如内存管理、垃圾回收等,可以增进对JVM的理解。 9. **...
飞信WebService接口调用源码是一份用于学习和开发飞信相关应用的重要资源。飞信,全称为“中国移动飞信”,是由中国移动推出的一款融合通信服务,它允许用户通过短信、语音、即时消息等多种方式在手机和电脑之间进行...
6. **DEMO分析**:`DHTest.rar`和`java封装接口智能交通DEMO.zip`可能包含大华SDK的示例代码和Java接口的封装。分析这些DEMO可以帮助开发者快速理解和学习如何使用SDK,通常DEMO会提供基础的设备连接、视频流获取等...
在IT行业中,调用外部接口是一项常见的任务...无论是服务端还是客户端,都需要对Java编程、网络通信和接口调用有一定的掌握。这个压缩包为开发者提供了一个良好的学习和实践平台,有助于提升其在实际项目中的应用能力。
JNI提供了一套接口,让Java虚拟机(JVM)能够调用本地方法,这些方法由C或C++编写,并编译成动态链接库(如Windows下的.dll或Linux下的.so文件)。JNI框架包括了Java端的本地方法声明和本地方法实现,以及C/C++端的...
本教程将深入探讨如何在Android中实现调用WebService接口进行登录功能,并基于提供的"login"源码进行分析。 首先,了解基础概念: 1. Android:Google开发的开源移动操作系统,主要应用于智能手机和平板电脑。 2. ...
1. **创建Java接口**:在Java代码中定义一个本地方法接口,这个接口将被C++代码实现。例如: ```java public class NativeDemo { static { System.loadLibrary("mylib"); } native void doSomething(); } ``...
Java WITSML客户端源码分析 WITSML(Well Intervention Transfer Format for Shared Data,井下作业数据共享格式)是一种开放标准,旨在促进油气行业的井下数据交换。它定义了一种结构化的方式,用于在不同软件系统...
首先,要实现这一目标,你需要安装Matlab的Java接口,即MATLAB Compiler SDK。这个SDK允许开发者将Matlab代码编译为可独立运行的Java类或者组件,以便在Java环境中调用。安装完成后,确保你的Java项目能够正确引用...
- **编写C++代码**:根据生成的头文件编写C++源码,实现本地方法的具体逻辑,并使用JNI函数调用Java代码。 - **编译本地代码**:为不同平台(Windows或Linux)编译本地代码,生成DLL或SO库。 - **加载库**:在...
这些API允许Java代码直接调用FFmpeg的C/C++接口,使得Java应用程序能够处理视频文件。 2. **视频格式转换**:源码可能包含将视频从一种编码格式(如MP4)转换为另一种(如AVI)的功能。这涉及到理解不同的编码标准...
本文将深入探讨Java代理方法的假设、验证以及Proxy类的源码分析。 首先,让我们理解Java代理的基本概念。在Java中,代理主要通过两种方式实现:接口代理(基于Java动态代理JDK Proxy)和类代理(基于CGLIB等库)。...
搏天API接口调用网站源码是一个用于与搏天API进行交互的软件开发资源,它提供了与搏天服务进行数据交换的功能。API(Application Programming Interface)是软件之间交互的桥梁,允许开发者通过发送请求获取所需的...