Di Jawa, Anda dapat mendefinisikan beberapa kelas tingkat atas dalam satu file, dengan ketentuan bahwa paling banyak salah satunya adalah publik (lihat JLS §7.6 ). Lihat di bawah sebagai contoh.
Apakah ada nama rapi untuk teknik ini (analog dengan
inner
,nested
,anonymous
)?JLS mengatakan sistem dapat memberlakukan pembatasan bahwa kelas-kelas menengah ini tidak dapat
referred to by code in other compilation units of the package
, misalnya, mereka tidak dapat diperlakukan sebagai paket-pribadi. Apakah itu benar-benar sesuatu yang berubah di antara implementasi Java?
misalnya, PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Jawaban:
Nama saya yang disarankan untuk teknik ini (termasuk beberapa kelas tingkat atas dalam satu file sumber) akan menjadi "berantakan". Serius, saya tidak berpikir itu ide yang bagus - saya akan menggunakan tipe bersarang dalam situasi ini sebagai gantinya. Maka masih mudah untuk memprediksi file sumber mana yang masuk. Saya tidak percaya ada istilah resmi untuk pendekatan ini.
Adapun apakah ini benar-benar berubah di antara implementasi - saya sangat meragukannya, tetapi jika Anda menghindari melakukannya sejak awal, Anda tidak perlu peduli :)
sumber
public int[] foo(int x)[] { return new int[5][5]; }
juga, meskipun itu valid.)javac tidak secara aktif melarang ini, tetapi ia memiliki batasan yang cukup banyak berarti bahwa Anda tidak akan pernah ingin merujuk ke kelas tingkat atas dari file lain kecuali ia memiliki nama yang sama dengan file itu.
Misalkan Anda memiliki dua file, Foo.java dan Bar.java.
Foo.java berisi:
Bar.java berisi:
Katakan juga bahwa semua kelas berada dalam paket yang sama (dan file-file tersebut di direktori yang sama).
Apa yang terjadi jika Foo.java merujuk ke Baz tetapi bukan Bar dan kami mencoba untuk mengkompilasi Foo.java? Kompilasi gagal dengan kesalahan seperti ini:
Ini masuk akal jika Anda memikirkannya. Jika Foo.java merujuk ke Baz, tetapi tidak ada Baz.java (atau Baz.class), bagaimana bisa javac tahu file sumber apa yang harus dicari?
Jika Anda sebaliknya memberitahu javac untuk mengkompilasi Foo.java dan Bar.java pada saat yang sama, atau bahkan jika Anda sebelumnya telah mengkompilasi Bar.java (meninggalkan Baz.class di mana javac dapat menemukannya) maka kesalahan ini hilang. Ini membuat proses pembuatan Anda terasa sangat tidak bisa diandalkan dan serpihan.
Karena batasan sebenarnya, yang lebih mirip "jangan merujuk ke kelas tingkat atas dari file lain kecuali jika itu memiliki nama yang sama dengan file itu atau Anda juga merujuk ke kelas yang ada di file yang sama yang bernama hal yang sama seperti file "agak sulit untuk diikuti, orang biasanya pergi dengan konvensi yang jauh lebih mudah (walaupun lebih keras) hanya menempatkan satu kelas tingkat atas di setiap file. Ini juga lebih baik jika Anda pernah berubah pikiran tentang apakah suatu kelas harus umum atau tidak.
Terkadang memang ada alasan bagus mengapa semua orang melakukan sesuatu dengan cara tertentu.
sumber
Saya yakin Anda cukup menyebutnya
PrivateImpl
apa adanya: anon-public top-level class
. Anda juga dapat mendeklarasikannon-public top-level interfaces
.misalnya, di tempat lain di SO: Kelas atas tingkat non-publik vs kelas bersarang statis
Adapun perubahan perilaku antara versi, ada diskusi tentang sesuatu yang "bekerja dengan sempurna" di 1.2.2. tetapi berhenti bekerja di 1.4 di forum sun: Java Compiler - tidak dapat mendeklarasikan kelas tingkat atas non publik dalam file .
sumber
non-public top level class
menjadi satu-satunya kelas dalam file, sehingga tidak mengatasi multiplisitas.secondary top level types
.Anda dapat memiliki kelas sebanyak yang Anda inginkan seperti ini
sumber
Demo file tunggal multi-kelas.
Saya tidak mengetahui ada yang tidak memiliki batasan itu - semua kompiler berbasis file tidak akan memungkinkan Anda untuk merujuk ke kelas kode sumber dalam file yang tidak bernama sama dengan nama kelas. (jika Anda mengkompilasi file multi-kelas, dan meletakkan kelas-kelas di jalur kelas, maka setiap kompiler akan menemukannya)
sumber
Menurut Java edisi 2 yang Efektif (Butir 13):
Kelas bersarang mungkin statis atau non-statis berdasarkan apakah kelas anggota perlu akses ke instance terlampir (Butir 22).
sumber
Ya Anda bisa, dengan anggota statis publik di kelas publik luar, seperti:
dan file lain yang merujuk pada di atas:
letakkan di folder yang sama. Kompilasi dengan:
dan jalankan dengan:
sumber
Hanya FYI, jika Anda menggunakan Java 11+, ada pengecualian untuk aturan ini: jika Anda menjalankan file java Anda secara langsung ( tanpa kompilasi ). Dalam mode ini, tidak ada batasan pada satu kelas publik per file. Namun, kelas dengan
main
metode harus yang pertama dalam file.sumber
Kamu tidak bisa. Tetapi sangat mungkin di Scala:
sumber