プライベートフィールドを持つクラス
皆さんはフィールド アクセス修飾子についてよく知っています。また、フィールドに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メソッドでは、クラスから 2 つのフィールドを取得します。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);
}
コードジム
リフレクションとオブジェクトへの参照の両方を使用してフィールドにアクセスできます。すべてが素晴らしいです!プライベートフィールドに移りましょう。
リクエストされたフィールドの名前をプライベートに変更します年分野:
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 は、アプリケーションがリフレクティブにインスタンス (配列以外) を作成したり、フィールドを設定または取得したり、メソッドを呼び出したりしようとしたときに、現在実行中のメソッドが指定されたクラス、フィールド、またはメソッドの定義にアクセスできないときにスローされます。メソッド、またはコンストラクター。
ここのメソッドもこの例外をスローします。この例外を回避するために、特別なメソッドを使用してプライベート フィールドにアクセスします。
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