おしりんブログ

新人PGおしりんの色々まとめるよブログ

FIELD OF VIEW

かっわいたーさっけびがー

ということでこんばんよ~

最近良く言われることは
「どこでぬるぽが出ているのか、ちゃんと確認しなさい。」です。

デバッグ大事や~今週は気をつけよ。


ということで、今日は最近ちょっとスゴーと思った
java.lang.reflect.Fieldについてまとめる。

(最近ブログネタディレクトリ作ったんだけど、ネタがたまる一方で全然消化出来てない)


さてさてそれではまとめに入っていこうじゃまいか。

…の前に、Fieldクラスが定義されてるjava.lang.reflectって
どんなクラスを定義するパッケージなの?という疑問が発生。


ということでAPIを確認したところ、

「クラスとオブジェクトに関するリフレクト情報を取得するクラス
およびインタフェースを提供します。」

と書いてありました。ほおお。


(´・ω・`)り、リフレクト情報ってなんや?

(`・ω・´)クラスの名前やメソッドの名前、パラメータとかの事やで

(なんだこれ)


些細な疑問も解決したところで、本題。

Fieldクラスで何が出来るのかというと、
その名の通り「フィールドの操作」が出来る。

  • フィールドの取得
  • フィールドに値をセット
  • フィールドの値を取得
  • staticフィールドアクセス

とかとか。


早速サンプルコードを書いてみる。


今回はHumanクラスを作成して、

public class Human {
  public String name;
  public String age;
}

class EarthHuman extends Human {
}

class VarsHuman extends Human {
}

このクラスのフィールドにアクセスしてみるよ。

import java.lang.reflect.Field;

public class FieldSample {
  public static void main(String[] args) throws NoSuchFieldException,
      SecurityException, IllegalArgumentException, IllegalAccessException {

    Human slaine = new EarthHuman();
    Human cruhteo = new VarsHuman();

    // Humanクラスのnameという名前のフィールドを取得する
    Field field = Human.class.getField("name");

    // フィールドに値をセットする
    slaine.name = "スレイン";
    field.set(cruhteo, "クルーテオ");

    // フィールドの値を取得
    System.out.println("EarthHuman:" + field.get(slaine));
    System.out.println("VarsHuman:" + field.get(cruhteo));
  }
}


出力結果は
EarthHuman:スレイン
VarsHuman:クルーテオ

ヒエエ。
(クルーテオ卿OPにも出演してるしあんな早期退場信じない)


フィールドの値を取得したいときとか便利。
めっちゃ便利。

オブジェクトだけ渡して、指定されたフィールドが存在すれば
フィールドに格納されてる値を返してくれる。

めっちゃ便利!


ちなみにField関係でもう一個めもっとくと、
Classクラス(なんかへん)のgetDeclaredFieldsメソッドもめっちゃ便利!

getDeclaredFieldsはオブジェクトのフィールドの全部を
ごそっと配列で返してくれるメソッド


使い方はこんな感じ。
(さっきのHumanクラスにちょいっと付け足す)

@Override
public String toString() {
  StringBuilder sb = new StringBuilder();
  // クラス名を取得
  sb.append("クラス: " + this.getClass().getCanonicalName() + "\n");
  sb.append("フィールド:\n");
  for (Field field : this.getClass().getDeclaredFields()) {
    try {
      field.setAccessible(true);
      sb.append(field.getName() + " = " + field.get(this) + "\n");
    } catch (IllegalAccessException e) {
      sb.append(field.getName() + " = " + "access denied\n");
    }
  }
  return sb.toString();
}


で、mainで

public static void main(String[] args) {

  Human slaine = new Human();
  slaine.name = "スレイン・トロイヤード";
  slaine.age = "16";
  
  System.out.println(slaine);
}


としてあげれば

クラス: Human
フィールド:
name = スレイン・トロイヤード
age = 16

という感じで出力される!ゴイスー!
(スレインたんキャワワ)


でもでも注意が必要なのは、Class.getDeclaredFields
オブジェクトのprivateや修飾子なしのフィールドは返してくれても、
継承フィールドは返してくれない。


今回はHumanクラスのtoString()をオーバーライドしてるから

Human slaine = new Human();
これだとフィールドを返してくれて

Human slaine = new EarthHuman();
これだとフィールドを返してくれない。


さっきサンプルコード書いてて知ったよ~
気をつけなきゃな~

それでは。スラマッパギー(ちがうな)