Apakah saya perlu berurusan dengan situasi di mana metode pribadi dipanggil melalui refleksi?

12

Saat membuat perpustakaan, haruskah saya memastikan bahwa metode pribadi harus bekerja seperti yang diharapkan ketika dipanggil bukan oleh metode lain dari kelas yang sama, tetapi oleh perpustakaan lain melalui refleksi ?

Misalnya, jika metode pribadi private DoSomething(int number)mengharapkan bahwa:

  • number adalah bilangan bulat nol-positif, dan:
  • variabel pribadi string abcbukan nol dan bukan string kosong,

dan sepenuhnya, jelek gagal jika kedua kondisi tidak cocok, haruskah saya menangani kegagalan itu bahkan jika saya tahu bahwa semua metode di kelas akan selalu¹ menetapkan nilai non-kosong abcsebelum memanggil DoSomething, dan memberikan bilangan bulat positif nol ke ini metode?

Dengan kata lain, apakah kode yang tidak dilindungi terhadap panggilan tidak aman melalui refleksi dapat dianggap sebagai kode berkualitas rendah , atau itu milik pemanggil yang menggunakan refleksi untuk memastikan bahwa panggilan itu tidak merusak apa pun?

Catatan: pertanyaan saya hanya mencakup satu set perpustakaan standar. Ini tidak mencakup kode yang harus sangat aman (yaitu ketika seseorang mungkin tertarik dengan menggunakan refleksi untuk membuatnya berperilaku tak terduga atau macet).


¹ Karena kelas didokumentasikan dengan benar, karena ada cukup unit test untuk memastikan bahwa pengembang lain tidak akan merusak metode ini, dll.

Arseni Mourzenko
sumber
Apakah kelas turunan dapat memanggil metode pribadi?
Oenone

Jawaban:

16

Dengan menandai metode Anda pribadi, Anda menetapkan niat dan kontrak Anda. Dengan menggunakan refleksi, kode klien dapat memilih untuk memutuskan kontrak ini dan konsekuensinya harus menanggung akibatnya. Hal yang sama terjadi dengan protokol, untuk hal-hal untuk bekerja aturan harus diikuti atau hal-hal buruk akan terjadi.

Masalah yang sama dapat terjadi dengan bahasa lain seperti C ++ di mana saya melihat hal-hal seperti

#define private public

Singkatnya - Anda TIDAK diharuskan untuk menghadapi situasi ini, penelepon harus tahu lebih baik.

Otávio Décio
sumber
3
Saya telah melihat orang-orang melemparkan kelas ke (unsigned char *), dan menulis langsung ke memori offset variabel anggota yang ingin mereka ubah. Mataku berdarah.
Shawn D.
6
Saya akan menambahkan bahwa pada dasarnya tidak mungkin untuk melindungi kelas Anda terhadap kode privilege berbahaya . Jika Anda entah bagaimana berhasil melindungi diri dari penggunaan refleksi yang tidak tepat maka seseorang akan menemukan cara berbeda untuk merusak hari Anda, mungkin hanya dengan menimpa memori proses Anda secara langsung. Pengkodean defensif pada akhirnya mencapai titik pengembalian yang menurun, dan refleksi sudah melewati titik itu.
Aaronaught
5

Jika ada yang menggunakan refleksi untuk memanggil metode pribadi Anda, itu pertanda bahwa seseorang melakukan sesuatu yang salah. Entah dia menggunakan kode dengan cara yang tidak dirancang untuk itu, atau Anda menyembunyikan terlalu banyak pekerjaan internal dan mematikan API.

Tapi sepertinya Anda belum sampai pada tahap itu, dan hanya mencoba bersikap pre-emptive. Jadi pendapat saya adalah: jangan khawatir tentang itu. Metode pribadi harus dianggap terlarang; jika seseorang dengan sengaja melanggar batasan itu, maka itu masalah mereka jika segalanya meledak.

Mike Baranczak
sumber
0

Yah, itu selalu ide yang baik untuk memvalidasi variabel non-lokal sebelum Anda menggunakannya, tetapi selain itu saya tidak akan khawatir tentang hal itu. Seperti yang dikatakan orang lain, Anda telah menetapkan niat Anda dengan menjadikan metode itu pribadi di tempat pertama; siapa pun yang menelepon dari luar kelas Anda tidak memiliki jaminan. Ketika bekerja di Jawa, saya bahkan tidak memberikan komentar javadoc pada metode pribadi saya, karena saya tidak ingin pengembang lain tahu bahwa mereka ada di sana.

TMN
sumber