JAva反射メカニズムの実戦例の共有
4207 ワード
まず、いくつかのクラスを知ってみましょう.
Class(java.lang.Class)
Classオブジェクトは特殊なオブジェクトで、クラスごとにクラスの「一般」オブジェクトを作成するClassオブジェクトがあります.オブジェクトのgetClass()メソッドで取得できます.
たとえば、この行のコードを実行します.
結果は次のとおりです.
このクラスはフィールドを表し、このフィールドを使用してクラスにアクセスできます.
次に、テストクラスを作成します.
次のメソッドを呼び出して、上記のクラスをテストします.
結果は次のとおりです.
これはbookオブジェクトの初期状態です
次に、反射メカニズムを使用してbookオブジェクトのlengthフィールドを取得し、変更して結果を表示します.
実行結果は次のとおりです.
lengthフィールドの値が変更されていることがわかります.
上で変更したのはint型の簡単なフィールドですが、実際にtitleフィールドのようなオブジェクトフィールドも変更できます.次の例を示します.
上のコード出力結果は次のとおりです.
実際には、すべてのStringタイプのフィールドを「グリーン童話」に変更し、すべてのintタイプのフィールドを199に変更します.私たちはこのフィールドがどういう意味なのかさえ知らない.
次にpagesというフィールドを変更します.このフィールドはArrayListです.ArrayListオブジェクトを作成し、オブジェクトを挿入します.
出力結果は次のとおりです.
Pageクラスを直接使用していないにもかかわらず、Pageオブジェクトが作成されていることがわかります.
Pageオブジェクトの作成文は:entityClass.新Instance()という言葉.新Instance文はClassオブジェクトの重要な方法であり、このクラスに対応するオブジェクトを作成するために使用されます.もちろん、クラスの構造方法のサポートが必要です.さらにgenGenericTypeメソッドにより,フィールドのタイプ修飾子を得ることができる.ここに置いて、取得したのがArrayListです.この文字列があれば、クラスローダClassを通過することができます.forNameはPageクラスをロードし、Pageオブジェクトを作成します.
Class(java.lang.Class)
Classオブジェクトは特殊なオブジェクトで、クラスごとにクラスの「一般」オブジェクトを作成するClassオブジェクトがあります.オブジェクトのgetClass()メソッドで取得できます.
たとえば、この行のコードを実行します.
System.out.println(" ".getClass().toString());
結果は次のとおりです.
class java.lang.String
Field(java.lang.reflect.Field)
このクラスはフィールドを表し、このフィールドを使用してクラスにアクセスできます.
次に、テストクラスを作成します.
class Book {
public String title;
public int length = 0;
public ArrayList pages = null;
@Override
public String toString() {
String sb = "Book:
";
sb += "title="+title+"
";
sb += "length=" + length + "
";
sb += "pages=" + pages + "
";
if (pages != null) {
for (Page page : pages) {
sb += page.toString();
}
}
return sb.toString();
}
}
class Page {
@Override
public String toString() {
return "page
";
}
}
次のメソッドを呼び出して、上記のクラスをテストします.
Book book = new Book();
System.out.println(book);
結果は次のとおりです.
Book:
title=null
length=0
pages=null
これはbookオブジェクトの初期状態です
次に、反射メカニズムを使用してbookオブジェクトのlengthフィールドを取得し、変更して結果を表示します.
Book book = new Book();
Class> aClass = book.getClass();
Field field = aClass.getField("length");
field.setInt(book, 9);
System.out.println(book);
実行結果は次のとおりです.
Book:
title=null
length=9
pages=null
lengthフィールドの値が変更されていることがわかります.
上で変更したのはint型の簡単なフィールドですが、実際にtitleフィールドのようなオブジェクトフィールドも変更できます.次の例を示します.
Book book = new Book();
Class> aClass = book.getClass();
Field[] fields = aClass.getFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.getType().equals(String.class)){
field.set(book, " ");
}else if(field.getType().equals(int.class)){
field.set(book, 199);
}
}
System.out.println(book);
上のコード出力結果は次のとおりです.
Book:
title=
length=199
pages=null
実際には、すべてのStringタイプのフィールドを「グリーン童話」に変更し、すべてのintタイプのフィールドを199に変更します.私たちはこのフィールドがどういう意味なのかさえ知らない.
次にpagesというフィールドを変更します.このフィールドはArrayListです.ArrayListオブジェクトを作成し、オブジェクトを挿入します.
Book book = new Book();
Class> aClass = book.getClass();
Field[] fields = aClass.getFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.getType().equals(ArrayList.class)){
String genric = field.getGenericType().toString();
String genricClass = genric.substring(
genric.indexOf(' genric.indexOf('>'));
Class> entityClass = Class.forName(genricClass);
Object obj = entityClass.newInstance();
ArrayList list = new ArrayList();
list.add(obj);
field.set(book, list);
}
}
System.out.println(book);
出力結果は次のとおりです.
Book:
title=null
length=0
pages=[page
]
Page
Pageクラスを直接使用していないにもかかわらず、Pageオブジェクトが作成されていることがわかります.
Pageオブジェクトの作成文は:entityClass.新Instance()という言葉.新Instance文はClassオブジェクトの重要な方法であり、このクラスに対応するオブジェクトを作成するために使用されます.もちろん、クラスの構造方法のサポートが必要です.さらにgenGenericTypeメソッドにより,フィールドのタイプ修飾子を得ることができる.ここに置いて、取得したのがArrayListです.この文字列があれば、クラスローダClassを通過することができます.forNameはPageクラスをロードし、Pageオブジェクトを作成します.