-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReflection.java
107 lines (94 loc) · 4.15 KB
/
Reflection.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import java.lang.reflect.*;
public class Reflection {
public static void main(String[] args) throws Exception {
// 「クラス」からクラス情報を取得
Class<?> cStatic = ReflectionTest.class;
// 「クラス情報」から引数を指定してコンストラクタ情報を取得
// -> NoSuchMethodException(検査例外)が発生する可能性があるため、
// 以下の方法でエラーハンドリングを行う必要がある
// 1. 呼び出すメソッド(=main())に"throws文"を付与
// 2. "try-catch文"で例外発生時の処理を記述
Constructor<?> con = cStatic.getConstructor(String.class, int.class);
// 「コンストラクタ情報」からオブジェクトの生成
// -> Constructor<?>型 -> 外部クラス型 へのキャストが必要
ReflectionTest ref = (ReflectionTest) con.newInstance("A", 5);
System.out.println("-- Before --");
System.out.println(ref);
System.out.println();
// 「オブジェクト」からクラス情報を取得
Class<?> cDynamic = ref.getClass();
// 「クラス情報」からフィールド情報を取得
// -> privateなメンバを取得する場合は"getDeclared*()"メソッドを利用
Field fStr = cStatic.getDeclaredField("str");
Field fInt = cDynamic.getDeclaredField("i");
// privateなフィールドのアクセス権限を変更
fStr.setAccessible(true);
fInt.setAccessible(true);
// 「フィールド情報」からオブジェクトの動的フィールドの値を変更
fStr.set(ref, "Changed");
fInt.set(ref, 13);
System.out.println("-- After --");
System.out.println(ref);
System.out.println();
// 「クラス情報」や各「メンバ情報」の修飾子を特定
// -> Modifierクラスの「クラス定数」を利用する場合
switch (cStatic.getModifiers()) {
case Modifier.PUBLIC:
System.out.println("Class " + cStatic.getSimpleName() + " is declared as public."); break;
case Modifier.PROTECTED:
System.out.println("Class " + cStatic.getSimpleName() + " is declared as protected."); break;
case Modifier.PRIVATE:
System.out.println("Class " + cStatic.getSimpleName() + " is declared as private."); break;
default:
System.out.println("Class " + cStatic.getSimpleName() + " is declared as default."); break;
}
Field fREF_S = cDynamic.getDeclaredField("REF_STATIC");
int modfREF_S = fREF_S.getModifiers();
// Modifierクラスの「クラスメソッド」を利用する場合
if (Modifier.isPrivate(modfREF_S)) {
System.out.print("Field " + fREF_S.getName() + " is declared as private");
if (Modifier.isStatic(modfREF_S)) {
System.out.print(", static");
if (Modifier.isFinal(modfREF_S)) {
System.out.println(", final.");
}
}
}
}
}
class ReflectionTest {
private String str = "";
private int i = 0;
// 動的final変数(利用しない)
private final String REF = "Final String(dynamic)";
// 静的final変数
private static final String REF_STATIC = "Final String(static)";
// デフォルトコンストラクタ
public ReflectionTest() {}
// オーバーロードしたコンストラクタ
public ReflectionTest(String str) {
this.str = str;
}
public ReflectionTest(int i) {
this.i = i;
}
public ReflectionTest(String str, int i) {
this.str = str;
this.i = i;
}
// オーバーロードした動的メソッド
public void add(String addStr) {
this.str += addStr;
}
public void add(int j) {
this.i += j;
}
public void add(String addStr, int j) {
this.str += addStr;
this.i += j;
}
@Override
public String toString() {
return "ReflectionTest(" + this.str + ", " + this.i + ") " + "[" + REF + ", " + REF_STATIC + "]";
}
}