Klase na may pribadong field

Alam na alam mong lahat ang tungkol sa mga modifier ng field access. At kung ang isang field ay may pribadong modifier, hindi namin maa-access ito mula sa labas.


public class Person {
  private int age;
  public String nickname;
  public Person(int age, String nickname) {
   this.age = age;
   this.nickname = nickname;
  }
}

Suriin natin ang pagiging naa-access sa ating Pangunahing klase:


public class Main {
   public static void main(String[] args) {
     Person person = new Person();  
     System.out.println(person.nickname);
    // System.out.println(person.age); No access to the field
  }
}

Wala kaming access saedadfield, ngunit mayroon tayong pagmuni-muni. :) At sa tulong nito, maaari tayong mag-access at magtrabaho kasama ang mga pribadong field.

Pagkuha ng pribadong field mula sa isang bagay gamit ang reflection

Kumuha tayo ng array ng lahat ng field sa ating klase gamit ang getDeclaredFields() method. Ibinabalik nito ang isang bagay na Field na maaari nating gamitin at baguhin:


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;
    }
pribadong edad
pampublikong palayaw

Sa pamamaraang getFieldNames , nakakakuha kami ng dalawang field mula sa aming klase. Ibinabalik ng getModifiers method ang modifier ng aming field, at ibinabalik ng getName ang pangalan nito. Ngayon subukan nating baguhin at i-access ang field na ito. Una, subukan nating kumuha ng data mula sa isang pampublikong field:


public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Person person = new Person(10, "CodeGym");

    Field field = Person.class.getDeclaredField("nickname");
    String nickname = (String) field.get(person);
    System.out.println(nickname);

    System.out.println(person.nickname);
}
CodeGym
CodeGym

Maaari naming ma-access ang field kapwa sa tulong ng pagmuni-muni at gamit ang aming sanggunian sa bagay. Lahat ay magaling! Lumipat tayo sa isang pribadong larangan.

Papalitan namin ang pangalan ng hiniling na field sa aming pribadoedadfield:


public static void main(String[]args)throws NoSuchFieldException, IllegalAccessException {
		Person person = new Person(10, "CodeGym");

    Field field = Person.class.getDeclaredField("age");
    int age =(int)field.get(person);
    System.out.println(age);

    // System.out.println(person.age);
}

Wala kaming access sa ginawang object, kaya subukang gumamit ng reflection. Nakakakuha kami ng error:

IllegalAccessException

Nakakakuha kami ng IllegalAccessException . Tingnan natin kung ano ang nasa loob:

Subukan nating malaman ito.

Ang isang IllegalAccessException ay itinapon kapag ang isang application ay nagtangkang gumawa ng isang instance (maliban sa isang array), magtakda o kumuha ng isang field, o mag-invoke ng isang paraan, kapag ang kasalukuyang nagsasagawa ng paraan ay walang access sa kahulugan ng tinukoy na klase, field, pamamaraan, o tagabuo.

Ang mga pamamaraan dito ay nagtatapon din ng pagbubukod na ito. Upang maiwasan ang pagbubukod na ito, gagamit kami ng isang espesyal na paraan upang ma-access ang pribadong field.

setAccessible(boolean flag)

Ginagawang posible ng pamamaraang ito na maiwasan ang mga pagsusuri sa pag-access sa seguridad para sa isang field o klase. Maaari naming ipasa ang totoo o mali sa pamamaraan upang matukoy kung isasagawa ang mga pagsusuri sa access sa seguridad para sa field. Subukan nating ayusin ang ating code:


public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Person person = new Person(10, "CodeGym");

    Field field = Person.class.getDeclaredField("age");
    field.setAccessible(true);

    int age = (int) field.get(person);
    System.out.println("The current value is " + age);
}

Tingnan natin ang resulta:

Ang kasalukuyang halaga ay 10

Malaki! Nakakuha kami ng impormasyon tungkol sa aming klase. Subukan din nating baguhin ang ating field sa pamamagitan ng pagtatalaga ng bagong value dito:


public static void main(String[]args)throws NoSuchFieldException, IllegalAccessException {
Person person = new Person(10, "CodeGym");

    Field field = Person.class.getDeclaredField("age");
    field.setAccessible(true);

    field.set(person, 19);

    int age =(int)field.get(person);
    System.out.println("The current value is " + age);
}

Pagkatapos baguhin ang aming field, nakukuha namin:

Ang kasalukuyang halaga ay 19

Subukan nating tawagan setAccessible(false) .


public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Person person = new Person(10, "CodeGym");

    Field field = Person.class.getDeclaredField("age");
    
    field.setAccessible(true);
    field.set(person, 19);
    field.setAccessible(false);

    System.out.println("The current value is " + field.get(person));
}

Pagkatapos ibalik ang pagiging naa-access sa false , tatakbo kami muli sa aming exception kapag sinubukan naming tawagan ang get method:

Kaya mag-ingat kapag nagtatrabaho sa mga pribadong larangan, at huwag kalimutan na ang pagmuni-muni ay isang napakalakas na tool!