Di Java, private
pengubah akses dianggap aman karena tidak terlihat di luar kelas. Kemudian dunia luar juga tidak tahu tentang metode itu.
Tapi saya pikir refleksi Java dapat digunakan untuk melanggar aturan ini. Pertimbangkan kasus berikut:
public class ProtectedPrivacy{
private String getInfo(){
return "confidential";
}
}
Sekarang dari kelas lain saya akan mendapatkan Info:
public class BreakPrivacy{
public static void main(String[] args) throws Exception {
ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
method.setAccessible(true);
Object result = method.invoke(protectedPrivacy);
System.out.println(result.toString());
}
}
Saat ini saya hanya berpikir metode private masih aman karena untuk melakukan hal-hal seperti diatas kita harus mengetahui nama metode. Tetapi jika kelas yang berisi metode privat yang ditulis oleh orang lain, kami tidak memiliki visibilitasnya.
Tetapi poin saya menjadi tidak valid karena baris kode di bawah ini.
Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();
Sekarang ini method[]
berisi semua hal yang perlu dilakukan di atas. Pertanyaan saya adalah, adakah cara untuk menghindari hal semacam ini dilakukan dengan menggunakan refleksi Java?
Saya mengutip beberapa poin dari Dokumentasi Java untuk memperjelas pertanyaan saya.
Tips Memilih Tingkat Akses:
Jika pemrogram lain menggunakan kelas Anda, Anda ingin memastikan bahwa kesalahan dari penyalahgunaan tidak dapat terjadi. Tingkat akses dapat membantu Anda melakukan ini. Gunakan tingkat akses paling ketat yang masuk akal untuk anggota tertentu. Gunakan pribadi kecuali Anda punya alasan kuat untuk tidak melakukannya.
sumber
getDeclaredMethods
akan mengembalikan nama yang terlihat seperti sampah.Jawaban:
Itu tergantung pada apa yang Anda maksud dengan "aman". Jika Anda menjalankan dengan manajer keamanan yang memungkinkan hal semacam ini, maka ya, Anda dapat melakukan semua jenis hal buruk dengan refleksi. Tapi kemudian dalam lingkungan semacam itu perpustakaan mungkin hanya bisa dimodifikasi untuk membuat metode menjadi publik.
Kontrol akses secara efektif "memberi nasihat" dalam lingkungan seperti itu - Anda secara efektif mempercayai kode untuk bermain dengan baik. Jika Anda tidak mempercayai kode yang Anda jalankan, Anda harus menggunakan pengelola keamanan yang lebih ketat.
sumber
check*
dasarnya memberikan pengecualian pada panggilan yang relevan .Pengubah akses tidak ada hubungannya dengan keamanan. Sebenarnya Anda dapat dan harus melihat pengubah akses sebagai kebalikan dari keamanan - ini bukan untuk melindungi data atau algoritme Anda, ini untuk melindungi orang dari persyaratan untuk mengetahui tentang data dan algoritme Anda. Inilah sebabnya mengapa pengubah default adalah paket - jika mereka mengerjakan paket, mereka mungkin perlu mengetahuinya.
Seiring dengan pengetahuan tentang data dan metode kode Anda, muncullah tanggung jawab untuk mengetahui kapan dan bagaimana menggunakannya. Anda tidak menempatkan privat pada metode inIt Anda untuk mencegah seseorang mengetahuinya, Anda melakukannya karena (a) mereka tidak akan tahu bahwa Anda hanya memanggilnya setelah foo dan hanya jika bar = 3.1415 dan (b) karena tidak ada gunanya mereka mengetahuinya.
Modifers akses dapat diringkas dalam kalimat sederhana "TMI, dude, aku jadi tidak perlu tahu bahwa".
sumber
Dengan mengatakan 'aman', Anda melindungi Anda atau pengembang lain, yang menggunakan API Anda untuk tidak merusak objek dengan memanggil metode pribadi Anda. Tetapi jika Anda atau mereka benar-benar perlu memanggil metode ini, mereka dapat melakukannya dengan Reflection.
sumber
Pertanyaannya adalah dari siapa Anda mencoba menyelamatkannya . Menurut pendapat saya, klien kode Anda yang seperti itu adalah orang yang merugi di sini.
Setiap bagian kode (ditulis oleh Anda atau orang lain) yang mencoba mengakses anggota
private
kelas di atas pada dasarnya menggali kuburannya sendiri.private
anggota tidak membuat bagian dari API publik dan dapat berubah tanpa pemberitahuan. Jika klien kebetulan mengonsumsi salah satu anggota privat dengan cara yang diberikan di atas, klien akan rusak jika meningkatkan ke versi API yang lebih baru di mana anggota privat dimodifikasi.sumber
Dengan fasilitas, ada tanggung jawab. Ada hal-hal yang tidak dapat Anda lakukan, & hal-hal yang dapat Anda lakukan tetapi tidak boleh Anda lakukan.
Pengubah pribadi disediakan / digunakan sebagai / dengan cara yang paling terbatas. Anggota yang tidak boleh terlihat di luar kelas harus didefinisikan sebagai pribadi. Tapi ini bisa dipatahkan dengan Refleksi seperti yang kita lihat. Tetapi ini tidak berarti bahwa Anda tidak boleh menggunakan pribadi - atau mereka tidak aman. Ini tentang Anda harus menggunakan hal-hal dengan bijaksana atau dengan cara yang konstruktif (seperti refleksi).
sumber
Dengan asumsi Anda mempercayai programmer klien API Anda, cara lain untuk melihat adalah seberapa 'aman' bagi mereka untuk menggunakan fungsi-fungsi khusus tersebut.
Fungsi Anda yang tersedia untuk umum harus menyediakan antarmuka yang jelas, terdokumentasi dengan baik, dan jarang berubah ke dalam kode Anda. Fungsi pribadi Anda dapat dianggap sebagai detail implementasi dan dapat berubah seiring waktu, jadi tidak aman untuk digunakan secara langsung.
Jika programmer klien berusaha keras untuk menghindari abstraksi ini, mereka dengan cara menyatakan bahwa mereka tahu apa yang mereka lakukan. Lebih penting lagi, mereka memahami bahwa itu tidak didukung dan mungkin berhenti berfungsi dengan versi kode Anda yang akan datang.
sumber
private
bukan untuk keamanan, ini untuk menjaga kode tetap bersih dan untuk mencegah kesalahan. Ini memungkinkan pengguna untuk memodularisasi kode (dan bagaimana itu dikembangkan) tanpa harus khawatir tentang semua detail dari modul lainSetelah Anda merilis kode, orang-orang dapat mengetahui cara kerjanya. Tidak ada cara untuk "menyembunyikan" logika jika pada akhirnya Anda ingin kode dijalankan di komputer. Bahkan mengompilasi ke biner hanyalah tingkat kebingungan.
Jadi, tidak mungkin Anda dapat menyiapkan API untuk melakukan hal-hal khusus yang Anda tidak ingin orang lain panggil. Dalam kasus API web, Anda dapat meletakkan metode yang ingin Anda kontrol di sisi server.
sumber