Saya sedang melihat kode Java LinkedList
dan memperhatikan bahwa itu menggunakan kelas bersarang statis Entry
,.
public class LinkedList<E> ... {
...
private static class Entry<E> { ... }
}
Apa alasan untuk menggunakan kelas bersarang statis, bukan kelas dalam normal?
Satu-satunya alasan saya bisa memikirkan, adalah bahwa Entri tidak memiliki akses ke variabel instan, jadi dari sudut pandang OOP memiliki enkapsulasi yang lebih baik.
Tapi saya pikir mungkin ada alasan lain, mungkin kinerja. Apa itu?
Catatan. Saya harap istilah saya sudah benar, saya akan menyebutnya kelas dalam statis, tetapi saya pikir ini salah: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
Jawaban:
Halaman Sun yang Anda tautkan memiliki beberapa perbedaan utama antara keduanya:
Tidak perlu
LinkedList.Entry
menjadi kelas tingkat atas karena hanya digunakan olehLinkedList
(ada beberapa antarmuka lain yang juga memiliki kelas bersarang statis bernamaEntry
, sepertiMap.Entry
- konsep yang sama). Dan karena tidak memerlukan akses ke anggota LinkedList, masuk akal jika itu statis - ini adalah pendekatan yang jauh lebih bersih.Seperti yang ditunjukkan oleh Jon Skeet , saya pikir itu adalah ide yang lebih baik jika Anda menggunakan kelas bersarang untuk memulai dengan itu menjadi statis, dan kemudian memutuskan apakah itu benar-benar perlu non-statis berdasarkan penggunaan Anda.
sumber
#comment113712_253507
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class
Bagaimana mungkin jika hanya paragraf sebelum dokumen mengatakan bahwa:Static nested classes do not have access to other members of the enclosing class
Mungkin mereka ingin mengatakan:A nested (non-static) class interacts with the instance members of its outer class (and other classes) just like any other top-level class
An inner class interacts with the instance members through an implicit reference to its enclosing class
, dan poin ini keluar properti lain yang menarik darinon-static inner classes
sertaanonymous inner classes
ataulocal classes defined inside a block
: mereka semua tidak dapat memiliki sebuahno-arg
konstruktor penyebabnya compiler secara implisit akan tambahkan urutan arg setiap konstruktor untuk lulus referensi dari sebuah contoh dari melampirkan yang kelas. Cukup mudah.Menurut saya, pertanyaannya seharusnya adalah sebaliknya ketika Anda melihat kelas dalam - apakah itu benar - benar perlu menjadi kelas dalam, dengan kompleksitas tambahan dan referensi IMO (implisit dan eksplisit) dari sebuah instance ke instance dari kelas yang mengandung?
Pikiran Anda, saya bias sebagai penggemar C # - C # tidak memiliki setara dengan kelas batin, meskipun memang memiliki tipe bersarang. Saya tidak bisa mengatakan saya telah melewatkan kelas dalam :)
sumber
Ada masalah penyimpanan memori yang tidak jelas untuk diperhitungkan di sini. Karena kelas dalam non-statis mempertahankan referensi implisit untuk kelas 'luar' itu, jika turunan dari kelas batin sangat direferensikan, maka instance luar juga sangat direferensikan. Hal ini dapat menyebabkan beberapa goresan kepala ketika kelas luar tidak mengumpulkan sampah, meskipun tampaknya tidak ada yang referensi.
sumber
Nah, untuk satu hal, kelas dalam non-statis memiliki bidang ekstra dan tersembunyi yang menunjuk ke instance kelas luar. Jadi jika kelas Entry tidak statis, maka selain memiliki akses yang tidak perlu, itu akan membawa sekitar empat petunjuk bukan tiga.
Sebagai aturan, saya akan mengatakan, jika Anda mendefinisikan kelas yang pada dasarnya ada untuk bertindak sebagai kumpulan anggota data, seperti "struct" di C, pertimbangkan menjadikannya statis.
sumber
Kelas dalam statis digunakan dalam pola pembangun. Kelas dalam statis dapat instantiate kelas luarnya yang hanya memiliki konstruktor pribadi. Jadi Anda dapat menggunakan kelas dalam statis untuk membuat instance kelas luar yang hanya memiliki konstruktor pribadi. Anda tidak dapat melakukan hal yang sama dengan kelas dalam karena Anda harus memiliki objek dari kelas luar yang dibuat sebelum mengakses kelas dalam.
Ini akan menghasilkan x: 1
sumber
kelas bersarang statis sama seperti kelas luar lainnya, karena tidak memiliki akses ke anggota kelas luar.
Hanya untuk kenyamanan pengemasan, kami dapat mengelompokkan kelas bersarang statis menjadi satu kelas luar untuk tujuan keterbacaan. Selain ini tidak ada kasus penggunaan lain dari kelas bersarang statis.
Contoh untuk penggunaan semacam itu, Anda dapat menemukan di file Android R.java (sumber daya). Folder res android berisi tata letak (berisi desain layar), folder yang dapat digambar (berisi gambar yang digunakan untuk proyek), folder nilai (yang berisi konstanta string), dll.
Karena semua folder adalah bagian dari folder Res, alat android menghasilkan file R.java (sumber daya) yang secara internal berisi banyak kelas bersarang statis untuk masing-masing folder dalamnya.
Berikut adalah tampilan dan nuansa file R.java yang dihasilkan di android: Di sini mereka hanya menggunakan untuk kenyamanan pengemasan.
sumber
Dari http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html :
sumber
Contoh sederhana:
Jika non-statis kelas tidak dapat dibuat instantiated dalam instance dari kelas atas (jadi tidak dalam contoh di mana utama adalah fungsi statis)
sumber
Salah satu alasan statis vs normal berkaitan dengan classloading. Anda tidak dapat membuat instance kelas dalam di konstruktor orang tua itu.
PS: Saya selalu mengerti 'bersarang' dan 'batin' bisa dipertukarkan. Mungkin ada nuansa halus dalam istilah ini, tetapi sebagian besar pengembang Java juga akan mengerti.
sumber
Kelas dalam yang tidak statis dapat menyebabkan kebocoran memori sementara kelas dalam yang statis akan melindungi mereka. Jika kelas luar menyimpan data yang cukup banyak, itu dapat menurunkan kinerja aplikasi.
sumber
Saya tidak tahu tentang perbedaan kinerja, tetapi seperti yang Anda katakan, kelas bersarang statis bukan merupakan bagian dari kelas tertutup. Tampaknya lebih mudah untuk membuat kelas bersarang statis kecuali Anda benar-benar membutuhkannya untuk menjadi kelas dalam.
Agak seperti mengapa saya selalu membuat variabel saya final di Jawa - jika mereka tidak final, saya tahu ada sesuatu yang lucu terjadi dengan mereka. Jika Anda menggunakan kelas dalam bukannya kelas bersarang statis, harus ada alasan yang bagus.
sumber
Menggunakan kelas bersarang statis daripada non-statis dapat menghemat ruang dalam beberapa kasus. Misalnya: menerapkan
Comparator
kelas di dalam, katakanlah Siswa.Kemudian
static
memastikan bahwa kelas Siswa hanya memiliki satu Pembanding, daripada membuat instance yang baru setiap kali instance siswa baru dibuat.sumber
Keuntungan dari class-- batin
Tanpa adanya kelas dalam maka kelas dalam tidak akan ada.
Ada empat jenis kelas batin.
titik ---
inorder untuk memanggil kelas dalam normal di daerah statis kelas luar.
Outer 0=new Outer(); Outer.Inner i= O.new Inner();
inorder untuk memanggil kelas dalam normal misalnya area kelas luar.
Inner i=new Inner();
inorder untuk memanggil kelas dalam normal di luar kelas luar.
Outer 0=new Outer(); Outer.Inner i= O.new Inner();
inside Inner class Ini pointer ke kelas batin.
this.member-current inner class outerclassname.this--outer class
untuk pengubah yang berlaku kelas dalam adalah - publik, default,
final,abstract,strictfp,+private,protected,static
outer $ inner adalah nama dari nama kelas dalam.
kelas dalam metode instance maka kita dapat mengakses bidang statis dan instance kelas luar.
Kelas 10.inner di dalam metode statis maka kita hanya dapat mengakses bidang statis
kelas luar.
sumber