java程序运行时是如何找到库函数并运行的?
PHP中文网
PHP中文网 2017-04-18 09:21:50
0
5
392

题主是一名C/C++程序员,刚开始学习java。

疑惑如下:

  1. java没有头文件,当调用第三方包(无源码)的方法,编译器如何保证程序员使用了正确的原型呢?

  2. 定义包时,为了保证包名唯一,使用package a.b.c语法,包的类需要在文件系统的a/b/c目录下。但当其他java程序使用该包时,这个路径信息怎么在运行查找这个包时体现?

  3. 某c程序编译时依赖库liba.so,那么运行时系统必须提供库liba.so,但是java程序编译时使用abc.jar,但是运行时可以提供bcd.jar,只要bcd.jar里具有该java程序用到的类就行?(我自己瞎猜的,请问这个说法对不对?)

最后,java有没有类似于《链接、装载与库》这样的书籍,或者请大家推荐一些可以了解原理的书籍,能够解答这些困惑,中英文皆可。

感谢。


非常感谢大家的解答,试着将各位的回答总结整理如下:

  1. jar包里的class文件中含有文件原型。c/c++的libxxx.so/libxx.a中只有符号,没有原型,原型由头文件中提供;java的class文件中即含有原型信息。编译器只要解析class文件即可知道程序员是否使用了正确的原型。(@fredric_201 与 @心不在焉 )

  2. jar包即zip包,里面存在目录结构,该结构与包名结构完全一致(标准jar包,非android jar包)。(@心不在焉 与 @beanlam)

  3. 说法正确。java程序依赖的实际是class,jar包只是一组class的zip包,其命名无关紧要,因此可以任意修改。如果非要和c/C++进行对比,libxx.so类似于.class,而非jar包。(@心不在焉 与 @beanlam)

笔者在ubuntu机器上使用zipinfo查看openjdk自带的jar包,如下:

prife@droi: /usr/lib/jvm/java-7-openjdk-amd64/jre/lib
$ zipinfo rt.jar
...
-rw----     2.0 fat    24298 bl defN 15-Jul-24 08:17 java/lang/String.class
-rw----     2.0 fat     1734 bl defN 15-Jul-24 08:17 java/lang/Object.class

可以看到rt.jar包里具有跟包名完全一致的目录结构。

最后感谢大家推荐的书籍:

《深入理解java虚拟机》
《Java Virtual Machine Specification》

PS. 笔者之所以对第二点看到困惑,因为作为Android程序员,发现安卓的jar包里是只有dex文件,没有包名的目录结构。

再次感谢大家的解答。

PHP中文网
PHP中文网

认证高级PHP讲师

répondre à tous(5)
左手右手慢动作

1. Le bytecode de Java contient les informations du prototype de la méthode, et le fichier de classe est requis lors de la compilation
2. Lorsque Java est en cours d'exécution, il recherche le fichier jar dans le chemin de classe, puis recherche le a. /b correspondant au nom du package dans le fichier jar. /c.class
3, c'est comme ça

伊谢尔伦

Lisez un livre sur JVM. Pour plus de détails, consultez le chargement de classe, « Machine virtuelle JVM approfondie ».
1. : Le nom complet de la classe définit une classe, et chaque classe est chargée une fois.
2. Demandez-vous comment le trouver ? Je pense que cela ressemble au nom complet de la classe.
Je ne comprends pas le dernier

黄舟

Ma compréhension personnelle est la suivante :
1. La bibliothèque compilée par c/c++ et le package jar généré par java ne sont pas équivalents. Le package jar est essentiellement un package compressé ; Le processus de compilation c/c++ doit être équivalent au processus de génération de fichiers de classe Java, c'est-à-dire que le code est converti en fichiers que la machine (ou la machine virtuelle) peut comprendre et exécuter
2. La machine virtuelle JAVA charge le ; fichier de classe cible dans la mémoire, les informations de classe doivent être placées dans la "zone de méthode". Lorsqu'elle est instanciée, la référence est sur la pile et l'instance est sur le tas (similaire à malloc ou new en c/c++).
3. Chaque classe est identifiée de manière unique dans la JVM à travers les trois parties d'informations : chargeur de classe + nom du package + nom de la classe
4. Les meilleurs livres incluent "Compréhension approfondie de la machine virtuelle Java", "OSGI". Principes et bonnes pratiques";

刘奇

1. Si A.java dépend du package xxx.jar, vous devez inclure xxx.jar dans le chemin de classe lors de la compilation (comme la commande javac). Lorsque le compilateur compile A.java, il recherchera xxx. jar pour voir s'il existe des classes dont A dépend, si les classes dont il dépend ont des méthodes correspondantes, etc. Je ne sais pas si c'est ce que vous avez dit pour vous assurer que le bon prototype est utilisé .

2. Java exige que le nom du package ait une structure de système de fichiers correspondante. Par exemple, le package com.x.y doit avoir un répertoire com/x/y/ correspondant. Ces informations de chemin se reflètent sous deux aspects, l’un lors de la compilation et l’autre lors de l’exécution.
La compilation et l'exécution doivent spécifier le chemin de classe. Ce chemin de classe peut être comparé au chemin de la variable d'environnement du système d'exploitation. Par exemple, si nous ajoutons la commande javac à la variable d'environnement path, nous devons ajouter le répertoire où. javac est situé sur le chemin.
Il en va de même pour le chemin de classe. Que ce soit lors de l'exécution ou de la compilation, si vous souhaitez référencer une classe, telle que com.a.b.String, alors vous devez d'abord disposer de la structure de répertoires correspondante com/a/b/. Vous pouvez placer le dossier com dans n'importe quel répertoire du disque dur, par exemple sous D:/test, vous devez alors ajouter D:/test au chemin de classe, de sorte que lorsque vous souhaitez référencer com.a.b.String, compiler le serveur ou Le runtime ira dans le répertoire spécifié par le chemin de classe pour le trouver. Comment le trouver ? Selon le nom du package, puis recherchez la structure de répertoires correspondante.
La structure des répertoires reflète son rôle ici.

3. Ne vous inquiétez pas du nom du package jar, car le package jar est en fait un fichier au format zip, et le package jar sera également ajouté au chemin de classe. Ce qui importe vraiment à la machine virtuelle Java. la structure de répertoires dans le package jar , pour déterminer le nom du package et l'emplacement de la classe, etc. Tant que le package Jar a une classe correspondante, vous pouvez renommer le package jar arbitrairement.

4. La différence entre Java et C/C++ est que Java s'exécute sur la machine virtuelle Java, donc si vous comprenez le mécanisme sous-jacent, vous examinerez probablement la machine virtuelle. La liaison et le chargement du C/C++ correspondent au principe du classloader (ClassLoader) en Java. Pour plus d'informations dans ce domaine, vous pouvez lire « Compréhension approfondie de la machine virtuelle Java » (Zhou Zhiming) ou la Spécification de la machine virtuelle Java officielle d'Oracle (jvms.pdf), qui peut être trouvée sur le site officiel. site web.
En fait, je pense que le problème de l'affiche concerne davantage les spécifications du langage Java lui-même. Pour cela, vous pouvez vous référer à certains tutoriels, ou à la Spécification officielle du langage Java(jls.pdf), d'Oracle. qui est également disponible dans Find it sur le site officiel d’Oracle.

小葫芦

Veuillez vous référer au chapitre 5 de « Spécifications de la machine virtuelle Java » : chapitre 5. Chargement, liaison et initialisation

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal