전용 필드가 있는 클래스
모두 필드 액세스 수정자에 대해 잘 알고 있습니다. 그리고 필드에 private 한정자가 있으면 외부에서 액세스할 수 없습니다.
public class Person {
private int age;
public String nickname;
public Person(int age, String nickname) {
this.age = age;
this.nickname = nickname;
}
}
Main 클래스 에서 접근성을 확인해 봅시다 .
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
}
}
우리는 액세스할 수 없습니다나이필드, 하지만 우리는 반영이 있습니다. :) 그리고 그것의 도움으로 우리는 개인 필드에 액세스하고 작업할 수 있습니다.
리플렉션을 사용하여 개체에서 개인 필드 가져오기
getDeclaredFields() 메서드 를 사용하여 클래스의 모든 필드 배열을 가져옵니다 . 작업하고 수정할 수 있는 Field 객체를 반환합니다 .
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;
}
공개 별명
getFieldNames 메서드 에서는 클래스에서 두 개의 필드를 가져옵니다. getModifiers 메서드는 필드의 수정자를 반환하고 getName은 해당 이름을 반환합니다. 이제 이 필드를 수정하고 액세스해 보겠습니다. 먼저 공개 필드에서 데이터를 가져오겠습니다.
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);
}
Code체육관
리플렉션의 도움과 개체에 대한 참조를 사용하여 필드에 액세스할 수 있습니다. 모든것이 좋아! 비공개 필드로 이동하겠습니다.
요청된 필드의 이름을 비공개로 변경합니다.나이필드:
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);
}
생성된 객체를 통한 접근 권한이 없으므로 리플렉션을 사용해 보세요. 오류가 발생합니다.
IllegalAccessException
IllegalAccessException 이 발생합니다 . 내부 내용물을 살펴보겠습니다.
그것을 알아 내려고합시다.
IllegalAccessException은 현재 실행 중인 메서드가 지정된 클래스, 필드, 메서드 또는 생성자.
여기에 있는 메서드도 이 예외를 throw합니다. 이 예외를 피하기 위해 비공개 필드에 액세스하는 특별한 방법을 사용합니다.
setAccessible(부울 플래그)
이 방법을 사용하면 필드 또는 클래스에 대한 보안 액세스 검사를 피할 수 있습니다. 필드에 대해 보안 액세스 검사를 수행할지 여부를 결정하기 위해 메서드에 true 또는 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);
int age = (int) field.get(person);
System.out.println("The current value is " + age);
}
결과를 살펴보겠습니다.
엄청난! 수업에 대한 정보를 얻었습니다. 또한 새 값을 할당하여 필드를 변경해 보겠습니다.
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);
}
필드를 변경한 후 다음을 얻습니다.
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));
}
접근성을 false 로 복원한 후 get 메서드 를 호출하려고 하면 예외가 다시 발생합니다 .
따라서 비공개 필드 로 작업할 때 주의 하고 리플렉션이 매우 강력한 도구임을 잊지 마십시오!
GO TO FULL VERSION