JAva反射メカニズムの実戦例の共有

4207 ワード

まず、いくつかのクラスを知ってみましょう.
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オブジェクトを作成します.