[Java] 31. Reflection機能を使う方法(Variable編)
こんにちは。明月です。
この投稿はJavaのReflection機能を使う方法(Variable編)に関する説明です。
以前の投稿でJavaのReflection機能をClassとMethodを分けて説明しました。
link - [Java] 29. Reflection機能を使う方法(Class編)
link - [Java] 30. Reflection機能を使う方法(Method編)
ClassとMethodにはStringでクラスやメソッドを探して割り当てすることや呼び出すことが重要なReflection機能でした。
このVariableでも別に違う機能があることではありません。
メンバー変数はOOPの特性でprivateのアクセス修飾子によりカプセル化します。
link - [Java] 14. オブジェクト指向プログラミング(OOP)の4つ特性(カプセル化、抽象化、継承、多相化)
普通はクラス内部でReflectionを利用して変数の値を取得することではないです。なので別に必要性がありません。
でも、クラスの外部でクラスの変数値を取得したい場合は?privateになっているから取得できないです。それがOOPの特性なので。
import java.lang.reflect.Field;
class Node {
// privateタイプ
private int data = 0;
// メンバー変数設定
public void setData(int data) {
this.data = data;
}
// メンバー変数リターン
public int getData() {
return this.data;
}
}
public class Example {
// 実行関数
public static void main(String... args) {
try {
// インスタンス生成
Node node = new Node();
// Reflectionでdata変数を取得する。
Field field = Node.class.getDeclaredField("data");
// setAccessibleはprivate、protectedタイプもアクセス可能にする。
field.setAccessible(true);
// dataフィールドに100を格納
field.set(node, 100);
// 結果は100が出力
System.out.println(node.getData());
} catch (Throwable e) {
e.printStackTrace();
}
}
}
上の例をみればNodeインスタンスを生成してgetDeclaredField関数でデータ値を取得します。
setAccessibleの関数はprivateの時にアクセスが可能にする関数です。
実はmainではNodeインスタンスのメンバー変数はprivateなのでアクセスができないです。
でも、上の例ではprivateになっているメンバー変数のデータを取得しました。そしてデータを格納することまでしました。
つまり、Reflectionを利用すればUnitテストのプログラムを作成する時、関数の結果だけではなく、途中のクラスのデバッグ値やメンバー変数の値を確認することができます。
import static org.junit.Assert.*;
import java.lang.reflect.Field;
import org.junit.Test;
class Node {
// privateタイプ
private int data = 0;
// メンバー変数の値を設定
public void setData(int data) {
this.data = data;
}
// メンバー変数の値をリターン
public int getData() {
return this.data;
}
}
public class TestCase {
// Unitテストを設定
@Test
public void test() {
try {
// インスタンス生成
Node node = new Node();
// dataフィールドに100を格納
node.setData(100);
// Reflectionでdata変数を取得する。
Field field = Node.class.getDeclaredField("data");
// setAccessibleはprivate、protectedタイプもアクセス可能にする。
field.setAccessible(true);
// データ検証
assertEquals(field.get(node), 100);
} catch (AssertionError e) {
throw e;
} catch (Throwable e) {
e.printStackTrace();
}
}
}
Reflectionのメソッドでもありますが、変数にもクラスの変数リストを取得する関数があります。
MethodではgetDeclaredMethods関数が呼ばされたクラスだけ、 getMethods関数は親クラスまでの関数がリストに出力されます。
変数は少し違いです。getDeclaredFieldsとgetFieldsの差異はgetDeclaredFieldsはprivateの含め変数、getFieldsはpublicだけの変数です。
普通のクラスはカプセル化になっているので、getFields関数は使うことではないですね。
リストだけではなく、変数名で取得する関数ても同じです。つまり、privateの変数をgetFieldに取得するとnullになります。こちらも変数がprivateタイプになっているのでgetDeclaredFieldだけ使うことになります。
ここまでJavaのReflection機能を使う方法(Variable編)に関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [Java] 38. Javaでウェブサービスプロジェクト(JSP Servlet)を作成する方法2019/10/01 21:48:08
- [Java] 37.イクリプス(eclipse)でトムキャット(tomcat)を設定する方法2019/09/30 22:19:34
- [Java] 36.コーディングする時、よく使うコーディングパターンとステップ数を減らす方法2019/09/27 20:39:09
- [Java] 35. コーディング規約設定(Google Standard coding style)2019/09/26 21:31:25
- [Java] 34. WindowでMariaDBをインストールする方法2019/09/25 19:58:30
- [Java] 33. オープンライブラリを参照する方法(eclipseからmavenを連結)2019/09/24 19:35:54
- [Java] 32. Reflection機能を使う方法(Annotation編)2019/09/24 00:19:25
- [Java] 31. Reflection機能を使う方法(Variable編)2019/09/20 22:34:40
- [Java] 30. Reflection機能を使う方法(Method編)2019/09/19 20:20:10
- [Java] 29. Reflection機能を使う方法(Class編)2019/09/18 20:02:14
- [Java] 28. 文字タイプ(CharacterSet)とエンディアン(endian)で変換する方法2019/09/17 20:22:02
- [Java] 27. ネットワーク通信(Socket)をする方法2019/09/16 23:42:46
- [Java] 26. ファイル(IO)を扱う方法(ファイル作成、ファイル修正、アクセス日付変更とIOをclose(リソース返却)する理由、Closableインタフェース)2019/09/13 20:03:58
- [Java] 25. Objectクラス(notify、waitの使い方)2019/09/13 00:58:31
- [Java] 24. Javaの同期化(Synchronized)とデッドロック(Deadlock)2019/09/11 23:06:09
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07