【Java入門】リフレクションでメソッドの実行、フィールドの変更

java reflection
長野 透
書いた人 長野 透
侍エンジニア塾ブログは、未経験からWebアプリ開発と仕事獲得をサポートする
侍エンジニア塾のオウンドメディアです。
プログラミング学習を覗き見

こんにちは!フリーランスの長野です。

Javaリフレクションって使ってますか?

リフレクションはクラスやメソッドを変数として扱うことができて、異なるクラスやメソッドを1つのプログラムで実行できるので便利です。

プログラムをテストする時などでよく使われたりします。

この記事では、リフレクションについて

・リフレクションとは
・リフレクションの使い方

という基本的な内容から、

・クラスの取得
・インスタンスの生成
・メソッドの取得と実行
・privateフィールドの参照と変更
・リフレクションの危険性について

など具体的な使い方についても解説していきます。

今回はリフレクションについて、使い方をわかりやすく解説します!

リフレクションとは

リフレクションとは、クラス名やメソッド名を指定して「クラスを動的に実行する」ことです。

「クラスを動的に実行する」とはクラス名やメソッド名を文字列の変数として指定することで、クラス名やメソッド名を変更してもプログラムが実行できるようにしています。

クラス名やメソッド名を変数として変更してもプログラムが実行できるので、プログラムのテストなどで使用されます。

ちなみに、コマンドラインでJavaのプログラムを実行する際に

と記述しますが、これもクラス名を変更してプログラムが実行できるのでリフレクションを行っていることになります。

リフレクションの使い方

リフレクションの使い方について、クラス、インスタンス、メソッド、フィールドの順にみていきましょう。

クラスの取得

クラスを取得するためにはClassクラスを使用します。

Classクラスの使い方は以下のようにいくつか方法があります。

foNameメソッドを使用する場合は、ClassNotFoundExceptionの例外処理を記述する必要があります。

なお、リフレクションに関連する例外の共通クラスReflectiveOperationExceptionで処理することも可能です。

インスタンスの生成

インスタンスを生成する記述は以下のとおりになります。

これは、

に相当します。

メソッドの取得と実行

メソッドを取得するにはMethodクラスのオブジェクトにgetMethodメソッドの戻り値を格納します。

getMethodメソッドの第2引数以降はClassクラスの可変長引数になります。

メソッドを実行するためにはinvokeメソッドを実行します。

invokeメソッドの第2引数以降は可変長引数になります。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、クラス名とメソッド名をそれぞれString型の変数に格納しています。

クラス名やメソッド名を格納した変数をforNameメソッド、getMethodメソッド、invokeメソッドなどのメソッドの引数に指定して実行しています。

privateフィールドの参照と変更

フィールドを取得するためには、getFieldメソッドを使います。

ただしアクセス修飾子privateで宣言されたフィールドを取得する場合は、getDeclaredFieldメソッドを使用します。

この場合、値を取得して変更するには、setAccessibleメソッドの引数をtrueに指定する必要があります。

getFieldメソッド、getDeclaredFieldメソッドの引数には取得するフィールド名を指定します。

フィールドを参照するには、getメソッドを使います。

getメソッドの引数には生成したインスタンスを指定し、取得したフィールドをオブジェクトで返します

フィールドを変更するには、setメソッドを使います。

setメソッドの第1引数には生成したインスタンスを、第2引数には変更後のフィールドの値をオブジェクトで指定します。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、まずstrMethod1で指定されたメソッドでフィールドに値を書き込んでいます。

その値をFieldクラスのオブジェクトfから呼び出されたgetメソッドを使って取得しています。

また、その値をオブジェクトfから呼び出されたsetメソッドを使って変更しています。

リフレクションの危険性について

リフレクションを使用する場合は以下のことに注意しましょう。

クラス設計を破壊する危険性

これまでお伝えしたように、アクセス修飾子privateで「カプセル化」した値を、直接取得・変更することができました。

このように直接操作することを可能にしてしまうため、リフレクションには既存のクラス設計を破壊してしまう危険性があります。

コンパイル時にエラーの検出対象外

以前はリフレクションを使用した部分のコードは、コンパイル時のエラー検出対象外でエラーを検出させることができませんでした。

リフレクション部分のエラーはプログラム実行時にのみ検出するしかありませんでした

しかし、Java7以降ではReflectiveOperationExceptionリフレクションに関連する例外の共通クラスが定義されたため、例外処理を記述できるようになりました。

まとめ

ここでは、リフレクションについて説明しました。

リフレクションを使って記述すれば、後はクラス名やメソッド名など変数に代入する値を変更するだけで異なるクラスやメソッドを実行することができます。

プログラムをテストする場合などで使用すると便利です。

使いこなすことができるように、この記事を何度も参考にして下さいね!

Javaカリキュラム無料公開中!
この記事はJava入門完全攻略ガイド【基礎学習/アプリ開発/仕事獲得】の一部になります。このカリキュラムは、プログラミング入門者が、基礎学習からアプリ開発、さらには仕事獲得まで体系的に学べる内容となっています。

Java学習に必要な情報を一つにまとめていますので効率よくJavaを学ぶことが出来ます。この機会に是非活用していただければと思います。


33歳、未経験だった僕がフリーエンジニアになれた理由
現在フリーでWEBエンジニアをやられている濱口直行さん。33歳で、プログラミングを学び始め、約半年という短い期間で独立までされた学習ログを余すことなくインタビューさせていただきました。

プログラミングを学習中の方はもちろん、独立をお考えの方まで幅広く活用できる記事になっています。この機会に是非活用していただければと思います。


最短でJavaを習得したい方へ

もし、あなたが、

「難しすぎて学習が全然進まない」
「学習量が膨大でゴールが見えない」
「エラーを解決するのに何日もかかってしまう」

など、プログラミング学習やキャリアに関してお困りであれば、まずは『無料体験レッスン』にお申し込み下さい。

あなたにとって、最適の解決策をご提案させていただきます。

詳しくは下の画像から詳しいサービス内容をご確認ください。

cta_bannar-java2

学習者インタビュー

人気講師インタビュー

人気記事セレクション

プログラミング学習者必見

専属講師に質問し放題、レッスンし放題!最短1ヶ月でフリーランスエンジニア
プログラミング学習カリキュラム無料公開中
Ruby学習カリキュラム無料公開中
Python学習カリキュラム無料公開中
 1記事最大11,000円!テックライター募集


LINEで送る
Pocket

この記事が気に入ったら
いいね!をしてフォローしよう

最新情報をお届けします

書いた人

長野 透

長野 透

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
[email protected]