Mengapa Java tidak mengizinkan penggunaan header seperti di C ++


18

Saya memiliki pertanyaan yang tidak saya temukan jawabannya kecuali jawaban berikut yang tidak memenuhi persyaratan saya:

"Karena James Gosling tidak mau"

Saya tahu bahwa Java dapat memiliki antarmuka (hanya fungsi virtual murni, tanpa atribut), tetapi itu tidak sama persis dengan definisi kelas.


14
Apa alasan kamu menginginkannya?

19
Untuk memiliki lebih banyak waktu untuk
perkelahian

6
Saya kira sebagian besar pengembang C ++ ingin sekali menyingkirkan mesin pengganti teks berusia 40 tahun yang menduplikasi ratusan kLoC untuk setiap file cpp, yang mengarah ke waktu kompilasi C ++ yang lama. Sebenarnya sistem modul yang tepat direnungkan untuk C ++ 11, tetapi jatuh karena kurangnya waktu. Saya kira itu akan muncul lagi.
sbi

Saya kira itu akan muncul lagi. Bahkan WG21 (kelompok kerja ISO C ++) memiliki kelompok studi semata-mata untuk tujuan mengevaluasi / mengembangkan konsep "modul" lebih lanjut: SG2 "Modul". Sayang sekali statusnya saat ini tidak aktif .
Max Truxa

Jawaban:


46

Jawaban berikut yang tidak memenuhi persyaratan saya: "Karena James Gosling tidak mau."

Tapi itu jawaban yang tepat. Tim desain bahasa (Gosling, Sheridan, Naughton, kemudian Bill Joy, Ken Arnold, dll) memutuskan header menyebabkan lebih banyak masalah daripada yang mereka pecahkan . Jadi mereka mendesainnya, dan menunjukkan bahwa mereka dapat membuat bahasa yang sangat berguna tanpa membutuhkannya.

Dari Bagian 2.2.1 buku putih Lingkungan Bahasa Jawa :

Kode sumber yang ditulis dalam Java sederhana. Tidak ada preprocessor, tidak ada #define dan kemampuan terkait, tidak ada typedef, dan tidak ada fitur-fitur itu, tidak ada lagi kebutuhan untuk file header. Alih-alih file header, file sumber bahasa Java memberikan definisi kelas lain dan metode mereka.

Definisi berlebihan, menyimpan file dalam sinkronisasi, definisi yang saling bertentangan, definisi tersembunyi - tidak ada yang terjadi di Jawa, karena Anda tidak memiliki header. Jika Anda ingin melihat definisi kelas telanjang, Anda dapat menghasilkan satu dari file .java secara langsung - misalnya sebagian besar IDE akan menunjukkan kepada Anda struktur kelas di bilah sisi, yang sama dengan hal yang sama.


6
Terima kasih atas jawaban Anda, karena itu, header menyebabkan lebih banyak masalah karena itu: Definisi berlebihan, menyimpan file dalam sinkronisasi, definisi yang bertentangan, definisi tersembunyi. Apakah itu sebabnya tidak diizinkan?
Etienne Noël

2
Perhatikan bahwa ada banyak pembicaraan tentang pertemuan Komite C ++ berikutnya karena mereka akan mempertimbangkan sistem "Modul" baru yang akan menjadi sistem yang lebih sederhana dan lebih efisien daripada memasukkan (dengan beberapa kesamaan dengan paket java, C # dll.) Tetapi masih retro -cocok dengan termasuk. Itu mengatakan bahwa sistem kompilasi yang lebih baik dapat, setidaknya secara teori, dapat digunakan untuk membuat kompilasi C ++ lebih baik / lebih efisien. Gosling benar saya kira, dan C ++ harus menemukan cara untuk memperbaiki sistem yang disertakan pula.
Klaim

5
Itu tidak bisa digunakan secara sempurna . Sistem Java build tidak dapat menentukan file mana yang harus dikompilasi ulang setelah perubahan kode. Suatu IDE akan menentukan file mana yang memerlukan perubahan kode, tetapi tidak yang membutuhkan kompilasi ulang. Jika metode tanda tangan berubah, tetapi perubahannya kompatibel dengan kode pada tanda tangan lama (mis. Mengubah tipe argumen dari float menjadi double), build bersih diperlukan untuk mencegah MethodNotFoundException.
kevin cline

1
@ kevin: Namun biasanya mungkin untuk hanya membangun kembali semuanya tanpa terlalu banyak biaya. Tidak seperti C ++ (tetapi seperti hampir semua bahasa kompilasi lainnya di bumi) Java tidak butuh waktu lama untuk mengkompilasi bahwa kompilasi parsial adalah optimasi yang sangat berguna dari alur kerja pengembangan Anda.
Donal Fellows

1
@ Donal: Memang benar bahwa kompilasi Java cukup cepat, tapi saya benci menebak apakah saya harus melakukan kompilasi ulang penuh atau tidak. Build seharusnya bekerja, setiap saat.
kevin cline

16

Tidak ada kebutuhan nyata dalam C ++ untuk memiliki definisi dan deklarasi kelas dalam file yang terpisah. Ini hanya berarti bahwa Anda dapat, setidaknya kembali pada hari C, melakukan parse dalam pemindaian atas-bawah tunggal kode. Pada mesin tanpa penyimpanan akses acak ini adalah masalah besar!

Memiliki tajuk juga memungkinkan Anda untuk menerbitkan antarmuka ke pustaka kode Anda dengan memasok tajuk tanpa perlu mengungkapkan kode sumber. Sayangnya di C ++ Anda juga harus mengungkapkan anggota data pribadi yang telah mengarah ke solusi seperti horor jerawat .

Ada upaya untuk membuat lingkungan C ++ di mana semuanya disimpan dalam struktur tipe database dan tidak ada file tetapi tidak berhasil.


Saya tahu itu, tetapi setidaknya Anda bisa melakukannya di C ++ bukan di Jawa; itu adalah pertanyaan utama saya. Terima kasih atas jawabannya.
Etienne Noël

14

Karena prinsip KERING . Di Jawa, informasi yang diperlukan untuk menggunakan kelas dalam suatu paket (atau kelas) terkandung di dalam file .class. Membuat file header terpisah yang berisi informasi yang sama akan melibatkan pengulangan di dua tempat.


Sayangnya, Anda sering ingin mengulanginya - pikirkan file wsdl, file idl dll. Satu menggambarkan antarmuka yang dapat Anda gunakan, dan file lain berisi implementasinya. Header C ++ adalah definisi antarmuka (buruk).
gbjbaanb

6

Dalam setiap bahasa - ada dua tahap untuk membuat kode biner akhir - kompilasi dan penautan (tentu saja, ada pemuatan tetapi itu tidak banyak berdampak di sini). Pada saat kompilasi, seseorang hanya perlu menempatkan kait (spesifikasi fungsi yang akan dipanggil) di tempat yang tepat. Linker sebenarnya bergabung mereka ketika kedua kode nyata tersedia. Sejauh ini tidak ada perbedaan antara C ++ dan Java.

Ada adalah , bagaimanapun, kebutuhan untuk C ++ untuk memiliki deklarasi dan definisi yang terpisah. Jika Anda menyimpan implementasinya di header, dan jika file header berubah, kode yang terhubung dengannya perlu dikompilasi ulang. Di mana seolah-olah definisi dalam file terpisah, kode hanya perlu dihubungkan kembali.

Memahami bahwa C ++ memang memiliki opsi untuk memiliki tautan statis yang menyiratkan bahwa kode objek diperbaiki bersama dengan aplikasi panggilan. Harap dicatat bahwa baik di C dan C ++, tidak valid untuk memiliki pemrograman dalam file header atau bahkan melakukan #include. itu hanya berarti bahwa Anda perlu repot tentang bagaimana menghubungkan terjadi dengan file objek ini.

Situasi di Jawa sangat berbeda. Setiap file kelas dikompilasi dengan file .class. Memang, kebutuhan untuk kompilasi fungsi kelas pemanggil yang disajikan sebagai bagian header dalam file .class. Namun, dalam Java final linking hanya dilakukan di dalam Runtime (mesin virtual) hanya dengan memberikan spesifikasi kode byte file kelas itu.

Lihat ini dan ini


4

Secara efektif antarmuka dan termasuk adalah header; definisi itu identik dengan binari, dan tidak bisa tidak selaras. Ini adalah salah satu keputusan desain terbaik di Jawa, tetapi ini adalah gangguan kecil karena tidak ada cara untuk menggabungkan deklarasi ini untuk kekompakan dan konsistensi.


1

Salah satu alasan yang baik untuk menyertakan adalah untuk memisahkan kode yang mungkin ingin Anda gunakan kembali (seperti definisi umum) dari kode yang khusus untuk proyek tertentu. Java ingin Anda menentukan hanya satu kelas atau antarmuka per file dan yang sebagian besar mengurangi kebutuhan untuk header yang disertakan - karena Anda akan memiliki bagian bersama yang sudah ada dalam file mereka sendiri.

Juga, kompiler dan sistem pembangunan mungkin ingin men-cache header yang sudah dikompilasi untuk menghindari penguraian lebih dari satu kali.


1
Saya kira Anda bisa menyimpan antarmuka dalam proyek bersama dan kemudian mengimplementasikannya dalam proyek independen
Alexander Mills
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.