Help us understand the problem. What is going on with this article?

JavaでReflection 第一回:コンストラクタ編

More than 5 years have passed since last update.

はじめに

javaを使ったアプリ開発でちょくちょくリフレクションを使用するけど、
いままで何となく使用していたので、備忘録変わりに今後複数回に分けて文書に
まとめてみようと思う。

本文

さて、今回は「第一回: コンストラクタ」編ということでコンストラクタを使用して
インスタンスを生成する方法について記載する。
検証用にBeanクラスとReflectionTestクラスを作成する。
ReflectionTestクラスから、Beanクラスで定義したコンストラクタを使用して
リフレクションによりインスタンスを生成するといった流れ。

Bean.java
public class Bean {

    public Bean(){
        this.pubVar = "default pubVar";
    };

    public Bean(String pubVar){
        this.pubVar = pubVar;
    };

    @SuppressWarnings("unused")
    private Bean(String[] args) {
        this.pubVar = args[0];
    }
    // instance var
    public String pubVar;
}
ReflectionTest.java
import java.lang.reflect.Constructor;


public class ReflectionTest {

    public static void main(String []args) throws Exception {

        // ①引数なしのコンストラクタを使用してインスタンス生成
        Bean bean = Bean.class.newInstance();
        System.out.println(bean.pubVar);    //  default pubVar

        // ②引数ありのコンストラクタを使用してインスタンス生成
        bean = Bean.class
                .getConstructor(String.class)
                .newInstance("引数ありコンストラクタの検証");
        System.out.println(bean.pubVar);    // 引数ありコンストラクタの検証

        // ③private コンストラクタを使用してインスタンス生成
        Class<?>[] params = {String[].class};
        Constructor<Bean> constructor = Bean.class
                .getDeclaredConstructor(params);
        constructor.setAccessible(true);
        bean = constructor
                .newInstance(new Object[]{new String[]{"プライベートコンストラクタの検証"}});
        System.out.println(bean.pubVar);    // プライベートコンストラクタの検証
    }
}

①引数なしのコンストラクタを使用してインスタンス生成

newInstance()メソッドを使用して
引数なしのデフォルトコンストラクタを呼び出しインスタンスを生成する。

②引数ありのコンストラクタを使用してインスタンス生成

まずは、Class.getConstructor()メソッドを使用してConstructor情報を取得する。
その際にgetConstructorメソッドの引数には、使用するコンストラクタの引数情報(class)を指定する。
またgetConstructorメソッドの引数は可変長引数なので引数の数に応じて「String.class, String.class」の様に引き渡す事が可能だ。
次に、生成したConstructorインスタンスのnewInstanceメソッドを使用してインスタンスを生成する。
その際にnewInstanceメソッドの引数にはコンストラクタに引き渡す引数を指定する。

③private コンストラクタを使用してインスタンス生成

Class.getDeclaredConstructor()メソッドを使用してConstructor情報を取得する。
※ Class.getConstructorメソッドは不可視な対象情報を取得できない為getDeclreadConstructorを使用する。というかこちらを使用しておけば問題ない?
次に、そのままnewInstanceメソッドでprivateコンストラクタからインスタンス生成しようとすると
java.lang.IllegalAccessExceptionが発生する。
そこで、constructor.setAccessible(true)メソッドを使用してリフレクション時にアクセス可能な様にアクセシビリティを緩くする。※セキュリティマネージャの設定により使用できない可能性がある。
その後、Constructor.newInstanceメソッドにて、インスタンスを生成する。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away