Semakan akses adalah untuk menyemak sama ada penggunaan atribut ahli dan kaedah ahli mematuhi hak akses (awam, dilindungi, lalai, peribadi).
Secara ringkasnya, jika kebenaran akses ahli kelas (atribut atau kaedah) adalah peribadi, maka ahli itu hanya boleh digunakan dalam kelas semasa kebenaran akses ahli adalah awam, maka ahli boleh digunakan dalam mana-mana kelas jika kebenaran akses ahli kelas adalah lalai, maka ahli hanya boleh digunakan dalam kelas di bawah pakej yang sama; daripada ahli kelas adalah Jika kebenaran dilindungi, maka ahli itu boleh digunakan dalam kelas di bawah pakej yang sama dan dalam subkelas kelas di bawah pakej lain.
Jika kebenaran akses ahli kelas adalah lalai, tetapi anda menggunakan ahli dalam pakej lain, Apabila menyusun, pengkompil akan melakukan semakan akses dan menemui penggunaan ahli Ia tidak konsisten dengan hak akses yang diberikan, jadi ralat akan dilaporkan.
Sebagai contoh, buat kelas Orang di bawah pakej com.example dengan empat pembolehubah ahli. Di bawah pakej com.example.app (yang merupakan pakej berbeza daripada com.example), gunakan empat pembolehubah ahli kelas Orang.
package com.example; package com.example; public class People { private int privateVar = 1; int defaultVar = 2; protected int protectedVar = 3; public int publicVar = 4; } package com.example.app; import com.example.People; public class TestMain { public static void main(String[] args) { People p = new People(); System.out.println(p.privateVar); System.out.println(p.defaultVar); System.out.println(p.protectedVar); System.out.println(p.publicVar); } }
Selepas penyusunan, ia digesa bahawa penggunaan publicVar mematuhi hak akses awam, jadi tiada ralat.
Saya percaya semua orang faham apa itu semakan akses Jadi, apakah semakan akses objek reflektif?
Atribut ahli, kaedah ahli dan pembina kelas masing-masing disarikan ke dalam kelas Medan, Kaedah dan Pembimbing semasa refleksi.
Kami boleh menggunakan Medan untuk mengakses atribut ahli objek Pengkompil tidak mengetahui kebenaran akses atribut ahli dan hanya mengetahuinya pada masa jalan. Oleh itu, semakan hak akses kepada objek reflektif (seperti Field) hanya boleh diserahkan kepada mesin maya.
Jika, apabila mesin maya sedang berjalan, didapati penggunaan ahli tidak konsisten dengan hak akses yang diberikan, kod berikut
package com.example.app; import com.example.People; import java.lang.reflect.Field; public class TestMain { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { People p = new People(); Class cl = p.getClass(); // 利用反射访问private修饰的成员变量 Field f = cl.getDeclaredField("privateVar") System.out.println(f.get(p)); } }
akan membuang pengecualian semasa menjalankan: java. lang.IllegalAccessException
Ringkasnya, semakan akses boleh dilakukan oleh pengkompil semasa penyusunan atau apabila mesin maya sedang berjalan (terutamanya untuk refleksi)
Kaedah setAccessible(boolean flag)
ialah kaedah dalam kelas AccessibleObject, iaitu kelas induk biasa bagi Field, Method dan Constructor. Apabila Medan, Kaedah atau Pembina (ketiga-tiganya ialah objek pantulan) digunakan untuk menetapkan medan (set(Object obj, Object value)
) atau mendapatkan medan (get(Object obj)
), kaedah panggilan (invoke(Object obj, Object... args)
) atau mencipta dan memulakan kejadian baharu kelas (newInstance(Object... initargs)
), semakan akses masa jalan akan dilakukan.
Dipetik daripada "Teknologi Teras Java Edisi Kesepuluh"
Nota: Nama kaedah setAccessible mudah mengelirukan kebolehaksesan ahli ditetapkan Contohnya, jika mereka merasakan ahli yang diubah suai awam boleh diakses oleh mana-mana kelas, bendera kebolehaksesan adalah benar jika mereka merasakan ahli yang diubah suai peribadi hanya boleh diakses oleh kelas ini, bendera kebolehaksesan adalah palsu. Malah, tidak kira apa hak akses, nilai bendera akses adalah palsu.
Kod ujian adalah seperti berikut:
package com.example.app; import com.example.People; import java.lang.reflect.Field; public class TestMain { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { People p = new People(); Class cl = p.getClass(); // 打印输出所有成员变量的名字及可访问标志 for (Field f : cl.getDeclaredFields()) { System.out.println(f.getName() + ": " + f.isAccessible()); } } }
Hasil input:
API di atas menjelaskan bahawa ini boleh diakses Bendera menunjukkan sama ada untuk menyekat semakan akses bahasa Java , nilai lalai adalah palsu, (diuji di atas)
boleh mengubah suai nilai lalai melalui setAccessible(true)
, yang akan menyekat pemeriksaan akses bahasa Java (Runtime) supaya ahli peribadi objek boleh diakses tanpa melaporkan ralat.
package com.example.app; import com.example.People; import java.lang.reflect.Field; public class TestMain { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { People p = new People(); Class cl = p.getClass(); for (Field f : cl.getDeclaredFields()) { //屏蔽对象的访问检查 f.setAccessible(true); // 访问不符合访问权限的成员属性 System.out.println(f.getName() + " = " + f.get(p)); } } }
Hasil input:
Atas ialah kandungan terperinci Cara menggunakan kaedah setAccessible() refleksi Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!