请问 C++这种支持多继承的语言是怎么跑在 JVM 上的?

2020-03-09 13:17:24 +08:00
 lbllol365
各位前辈好,没毕业小菜鸟在看《深入理解 Java 虚拟机》时有一个如题的疑惑,想请教大家。

是这样的:我在看到第六章 类文件结构时,看到“super_class (父类索引)”这个字段,书上说“由于 Java 语言不允许多继承,所以父类索引只有一个”。我联想到 JVM 是语言无关的,所以我当时觉得 JVM 应该会支持多个父类索引吧。然后我去查了 Java SE 8 的 JVM 规范,里面说 super_class 这个索引指向一个“ CONSTANT_Class_info”结构,然后我看这个结构是代表一个类或者接口( The CONSTANT_Class_info structure is used to represent a class or an interface )。那么这样是不是可以认为 JVM 在“super_class"这一字段上不支持多继承?然而我们又知道 C++是可以跑在 JVM 上的? But how ?

懂的前辈点一个关键点就可以了,我自己去查资料就好。谢谢!
3869 次点击
所在节点    Java
31 条回复
tabris17
2020-03-09 13:19:36 +08:00
把 C++代码编译成 JVM 的字节码,不需要用到类结构都是可以的
jinsongzhao
2020-03-09 13:26:12 +08:00
jni 接口调用动态连接库实现调用 C++库的吧,这种模式不算跑在 JVM 上,是使用本地 CPU 指令运行了。
参见: https://www.cnblogs.com/sunseine/p/3964828.html
lbllol365
2020-03-09 13:29:36 +08:00
@tabris17 不需要强制遵守 class 文件格式和语法吗?还是“类结构”不属于 class 文件强制要求的内容?这个我去查一下。
lbllol365
2020-03-09 13:32:10 +08:00
@jinsongzhao 这种情况我了解的。要是直接编译成 JVM 字节码呢
augustheart
2020-03-09 13:37:40 +08:00
什么叫做 c++跑在 jvm 上?
jvm 上面跑的也不是 java,而是 java 字节码。
BrettD
2020-03-09 13:38:48 +08:00
C++不是直接编译成目标架构二进制机器码吗,怎么运行在 JVM 上呢?
augustheart
2020-03-09 13:40:45 +08:00
@BrettD 虽然没人做这种无聊东西,不过理论上 c++编译成 java bytecode 也是可以的吧……
augustheart
2020-03-09 13:41:26 +08:00
@BrettD llvm 不熟,不知道有没有做过这事
lbllol365
2020-03-09 13:45:09 +08:00
@augustheart 嗯,确实说的不清楚,应该是“C++编译为 JVM 字节码,跑在 JVM 上”。感谢提醒
lbllol365
2020-03-09 13:47:17 +08:00
@BrettD C++编译为 JVM 字节码,跑在 JVM 上。虽然在工程上很扯,但是 JVM 不是声称“语言无关性”吗,所以想探究这种可能。
ipwx
2020-03-09 13:48:34 +08:00
首先,我没见过 C++ target JVM 的编译器。

不过就算 JVM 本身没支持多继承,你在转义过程中加点料不就能支持了。反正 C++ 那种多继承,RTTI 弱到爆炸,只要编译器足够牛逼,什么都能模拟。
augustheart
2020-03-09 13:52:12 +08:00
@lbllol365 虽然我不熟悉 java 这块,不知道有哪个项目把 c++编译成 java 字节码,但是假如真的有这么一个项目,只要它是真的支持 jvm,那么它的 target 就是 jvm,和 target 是 linux、windows 之类的一回事。生成对应平台的目标就要支持对应平台的规范。
回到你的困惑,与 jvm 的语法也不等于 java 的语法一样,机器码 /汇编的语法和 c++的语法也不是一回事。语言层的概念在最终目标里面完全是另外一回事。
lbllol365
2020-03-09 13:54:16 +08:00
@ipwx 我是在用必应搜索这个问题时,看到了知乎的这个问题 https://www.zhihu.com/question/51380338

嗯,我再去查一下
augustheart
2020-03-09 13:57:03 +08:00
另外这个事可以参考一下 java 那个没有血缘关系的亲兄弟 c#扩展一下思考。c++/clr 就是整个把.net 与机器码混合在一起跑了。
az467
2020-03-09 13:57:34 +08:00
>我们又知道 C++是可以跑在 JVM 上的

反正我不知道 = =,我只知道出现过几个 c2j 转换器,不过貌似理论上是可以的。
JVM 的底层结构又不影响顶层语言怎么实现,用别的办法去模拟就好了(比如增加一个 list 属性)。

你非要深究的话,Python 支持多继承,你可以查查看 Jython 是怎么实现的。

PS:java 本身就能通过接口实现多继承。
ipwx
2020-03-09 14:02:07 +08:00
> PS:java 本身就能通过接口实现多继承。

www 其实 Scala 也有 trait,模拟多继承,一般情况下够用了。
lbllol365
2020-03-09 14:02:31 +08:00
@augustheart 行,我去看一下
ipwx
2020-03-09 14:04:16 +08:00
看了楼主的新的追加,我觉得大可以用一句话高屋建瓴,解决楼主的一切疑惑:

“图灵完全的任何 computing machine 都是等价的。”

JVM 是图灵完全的,C++ 是图灵完全的。所以它们都可以互相表达,只是效率高低、以及实现细节的繁易问题罢了。

至于 Open Source Project ?我没见过实用的。如果说要看 toy project,那随便搜,肯定有。
lbllol365
2020-03-09 14:10:08 +08:00
我还是看得东西少啊,太菜了,谢谢各位了,自闭学习了......
augustheart
2020-03-09 14:16:10 +08:00
@lbllol365 老实说,可能你会越看越糊涂,我说完就后悔了,因为研究 clr 就扯远了……
你先回顾一下编译的具体过程。把 c++解析为语法树。然后从语法树产生 ir,在 ir 这个阶段它就是平台无关了。也就是说,接下来就是从 ir 转换到 jvm 字节码了。
然后需要考虑的就是 ir 怎么对应到 jvm,但是从我这个半桶水 c++er 来看,这个可能只是个苦力活。
当然,实际写一个这种东西的困难还有包括 java 的标准库的调用。这个就真的可以参考 c++/clr 了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/651159

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX