Private maydonga ega bo'lgan klass
Har biringiz maydonning kirish modifikatorlari haqida yaxshi bilasiz. Agar maydonga private modifikatori o'rnatilgan bo'lsa, bizda tashqaridan kirish imkoniyati bo'lmaydi.
public class Person {
private int age;
public String nickname;
public Person(int age, String nickname) {
this.age = age;
this.nickname = nickname;
}
}
Main da mavjudlikni tekshiramiz:
public class Main {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.nickname);
//System.out.println(person.age); maydonga kirish yo'q
}
}
Maydon age ga kirish yo'q, lekin refleksiya mavjud. Uning yordamida biz private maydonlariga kirish va ularni ishlatishimiz mumkin.
Refleksiya orqali obyektning privat maydonini olish
Endi getDeclaredFileds() metodi yordamida klassimizdagi barcha maydonlar massivini olamiz. U bizga Fileds klassini qaytaradi, bu bilan biz keyingi ishlaymiz va o'zgartiramiz:
public static void main(String[] args) {
Field[] fields = Person.class.getDeclaredFields();
List<String> actualFieldNames = getFieldNames(fields);
actualFieldNames.forEach(System.out::println);
}
static List<String> getFieldNames(Field[] fields) {
List<String> fieldNames = new ArrayList<>();
for (Field field : fields)
fieldNames.add(Modifier.toString(field.getModifiers()) + " " + field.getName());
return fieldNames;
}
public nickname
getFieldNames metodida biz klassimizdan ikkita maydonni olamiz. getModifiers metodi bizga maydonimizning modifikatorini qaytaradi va getName — nomini. Endi maydonga kirish va uni o'zgartirishga harakat qilamiz. Avvaliga jamoatchilik maydonidan ma'lumot olishni sinab ko'ramiz:
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Person person = new Person(10, "javaRush");
Field field = Person.class.getDeclaredField("nickname");
String nickname = (String) field.get(person);
System.out.println(nickname);
System.out.println(person.nickname);
}
javaRush
Refleksiya orqali ham, obyektga murojaat qilish orqali ham maydonga kirish imkoniyati mavjud. Ajoyib! Privat maydon tomon harakatlanamiz.
Olishni istagan maydon nomini privat maydon age ga o'zgartiramiz:
public static void main(String[]args)throws NoSuchFieldException, IllegalAccessException{
Person person = new Person(10, "javaRush");
Field field = Person.class.getDeclaredField("age");
int age =(int)field.get(person);
System.out.println(age);
//System.out.println(person.age);
}
Klassning yaratilgan nusxasi orqali kirish yo'q, shuning uchun refleksiya orqali sinab ko'ramiz va xatoga duch kelamiz:
IllegalAccessException
Bizda IllegalAccessException yuzaga keladi. Endi ichkariga kiramiz va ichida nima borligini ko'rib chiqamiz:
Tushunishga harakat qilamiz.
IllegalAccessException istisnosi, dastur reflektiv ravishda nusxa yaratishga (massivdan tashqari), maydon yoki metodga qiymat belgilab olishga harakat qilganida sodir bo'ladi, lekin ayni vaqtda bajarilayotgan metod ko'rsatilgan klass, maydon, metod yoki konstruktorga kirish huquqiga ega emas.
Bu istisnoni chiqaradigan metodlar ham mavjud. Bunday istisnoning oldini olish uchun privat maydonga kirish uchun maxsus metoddan foydalanamiz.
setAccessible(boolean flag)
Ushbu metod klass maydoni yoki metodga kirish tekshiruvidan qochish imkonini beradi. Metodga biz true yoki false parametrini berishimiz mumkin, bu kirish tekshiruvi kerakmi yoki yo'qligini belgilaydi. Kodimizni tuzatishga harakat qilamiz:
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Person person = new Person(10, "javaRush");
Field field = Person.class.getDeclaredField("age");
field.setAccessible(true);
int age = (int) field.get(person);
System.out.println("Joriy qiymat - " + age);
}
Natijaga qaraymiz:
Ajoyib, klassimiz ma'lumotlarini oldik. Shu bilan birga, maydonimizni o'zgartirib, yangi qiymat belgilashga harakat qilaylik:
public static void main(String[]args)throws NoSuchFieldException, IllegalAccessException{
Person person = new Person(10, "javaRush");
Field field = Person.class.getDeclaredField("age");
field.setAccessible(true);
field.set(person, 19);
int age =(int)field.get(person);
System.out.println("Joriy qiymat - " + age);
}
Maydonimizni o'zgartirishga harakat qilish va natijani olish:
setAccessible(false) ni sinab ko'ramiz.
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Person person = new Person(10, "javaRush");
Field field = Person.class.getDeclaredField("age");
field.setAccessible(true);
field.set(person, 19);
field.setAccessible(false);
System.out.println("Joriy qiymat - " + field.get(person));
}
Kirishni false ga qaytarib borganimizdan so'ng, get metodini chaqirishga harakat qilganimizda yana istisnomizga duch kelamiz:
Shuning uchun private maydonlar bilan ishlayotganingizda ehtiyot bo'ling va refleksiya juda kuchli vosita ekanligini unutmang!
GO TO FULL VERSION