cari

Rumah  >  Soal Jawab  >  teks badan

java程序运行时是如何找到库函数并运行的?

题主是一名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中文网2812 hari yang lalu400

membalas semua(5)saya akan balas

  • ringa_lee

    ringa_lee2017-04-18 09:23:50

    1. Bytecode Java mengandungi maklumat prototaip kaedah dan fail kelas diperlukan semasa menyusun
    2 Apabila Java sedang berjalan, ia mencari fail jar dalam laluan kelas, dan kemudian mencari a /b sepadan dengan nama pakej dalam fail jar /c.class
    3, ia seperti ini

    balas
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 09:23:50

    Baca buku tentang JVM Untuk butiran khusus, lihat pemuatan kelas, "Mesin Maya JVM yang mendalam".
    1.: Nama kelas penuh mentakrifkan kelas dan setiap kelas dimuatkan sekali.
    2. Adakah anda bertanya bagaimana untuk mencarinya?
    Saya tidak faham yang terakhir

    balas
    0
  • 黄舟

    黄舟2017-04-18 09:23:50

    Pemahaman peribadi saya ialah:
    1. Pustaka yang disusun oleh c/c++ dan pakej jar yang dihasilkan oleh java tidak setara Pakej jar pada asasnya hanya pakej termampat, jika anda perlu membuat analogi proses penyusunan c/c++ harus bersamaan dengan proses Java menjana fail kelas, iaitu, kod ditukar kepada fail yang mesin (atau mesin maya) boleh memahami dan melaksanakan
    2. Mesin maya JAVA memuatkan sasaran fail kelas ke dalam memori , maklumat kelas harus diletakkan di "kawasan kaedah".
    3. Setiap kelas dikenal pasti secara unik dalam JVM melalui tiga bahagian maklumat: pemuat kelas + nama pakej + nama kelas
    4 termasuk "Pemahaman Mendalam tentang Mesin Maya Java", "OSGI Prinsip dan Amalan Terbaik";

    balas
    0
  • 怪我咯

    怪我咯2017-04-18 09:23:50

    1. Jika A.java bergantung pada pakej xxx.jar, anda perlu memasukkan xxx.jar dalam classpath semasa penyusunan (seperti arahan javac apabila penyusun menyusun A.java, ia akan mencari xxx). jar untuk melihat sama ada terdapat kelas yang bergantung pada A, sama ada kelas yang bergantung padanya mempunyai kaedah yang sepadan, dsb. Saya tidak tahu sama ada ini yang anda katakan untuk memastikan prototaip yang betul digunakan .

    2. Java memerlukan nama pakej mesti mempunyai struktur sistem fail yang sepadan Sebagai contoh, pakej com.x.y mesti mempunyai direktori com/x/y/ yang sepadan dengannya. Maklumat laluan ini dicerminkan dalam dua aspek, satu adalah semasa menyusun, dan satu lagi adalah semasa berjalan.
    Kedua-dua kompilasi dan larian mesti menentukan laluan kelas ini boleh dibandingkan dengan laluan pembolehubah persekitaran sistem pengendalian Contohnya, jika kita menambah arahan javac pada pembolehubah persekitaran laluan, kita perlu menambah direktori di mana javac terletak di laluan.
    Begitu juga dengan classpath sama ada semasa berjalan atau kompilasi, jika anda ingin merujuk kelas, seperti com.a.b.String, maka anda mesti mempunyai struktur direktori yang sepadan com/a/b/ dahulu. Anda boleh meletakkan folder com dalam mana-mana direktori pada cakera keras, contohnya, di bawah D:/test, maka anda perlu menambah D:/test pada laluan kelas, supaya apabila anda ingin merujuk com.a.b.String, kompilkan pelayan atau runtime akan pergi ke direktori yang ditentukan oleh classpath untuk mencarinya Menurut nama pakej, kemudian cari struktur direktori yang sepadan.
    Struktur direktori menggambarkan peranannya di sini.

    3. Jangan risau tentang nama pakej jar, kerana pakej jar sebenarnya adalah fail dalam format zip, dan pakej jar juga akan ditambahkan pada classpath struktur direktori dalam pakej balang , untuk menentukan nama pakej dan lokasi kelas, dsb. Selagi pakej Jar mempunyai kelas yang sepadan, anda boleh menamakan semula pakej jar dengan sewenang-wenangnya.

    4. Perbezaan antara Java dan C/C++ ialah Java berjalan pada mesin maya Java, jadi jika anda memahami mekanisme asas, kemungkinan besar anda akan melihat mesin maya. Pemautan dan pemuatan C/C++ sepadan dengan prinsip pemuat kelas (ClassLoader) di Java. Untuk maklumat di kawasan ini, anda boleh membaca "Pemahaman Mendalam tentang Mesin Maya Java" (Zhou Zhiming), atau Spesifikasi Mesin Maya Java rasmi Oracle (jvms.pdf), yang boleh didapati di laman web rasmi. laman web.
    Sebenarnya, saya rasa masalah poster adalah lebih kepada spesifikasi bahasa Java itu sendiri Untuk ini, anda boleh merujuk beberapa buku tutorial, atau rasmi Oracle Spesifikasi Bahasa Java(jls.pdf), yang juga tersedia dalam Cari di laman web rasmi Oracle.

    balas
    0
  • 高洛峰

    高洛峰2017-04-18 09:23:50

    Sila rujuk Bab 5 "Spesifikasi Mesin Maya Java": Bab 5. Memuatkan, Memaut dan Memulakan

    balas
    0
  • Batalbalas