• ベストアンサー

Class.forName("Hogehoge")の使い方

Class.forName("Hogehoge");は 動的にクラス(この例では"Hogehoge")をロードする場合に使用するとの説明が当Q&Aに記載されていましたが、次のコーディング例が有りました。 Hogehoge hh = Class.forName("Hogehoge").newInstance(); この例では、リターンを受けるクラス名が、動的に指定されていないため、具体的な利用方法が分かりませんでした。 よろしく、ご教示いただければ幸甚です。

  • Java
  • 回答数6
  • ありがとう数17

質問者が選んだベストアンサー

  • ベストアンサー
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.5

#2です。 >Menuにクラス名を登録しておき、指定されたMenuのクラスをスタートするような ことを考えていました。 1つのメニュー項目(メニュー機能)に1つのクラスを対応させ、 選択されたメニュー項目に対応したクラスを実行するわけですね。 その場合、それらのクラスには全て「メニュー項目になる」という共通点がありますね? その共通点をインターフェースとして定義しておきます。 interface IMenuItem {  /** メニュー項目の名前*/  public String getCommandName();  /** メニュー項目の実行*/  public void execute(); } 全てこのインターフェースを実装して下さい。 また、実行時には Class cls = Class.forName(className); IMenuItem menuItem = (IMenuItem)cls.newInstance(); menuItem.execute(); となります。

chachax
質問者

お礼

有難うございます。 目から鱗の思いです。

その他の回答 (5)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.6

#5です。もう少し、補足しておきます。 前回も示した通り、Class.forName("").newInstance()で受ける型は、 ある程度限定して使うことがほとんどです。 逆に、限定しない(Object型で受ける)ということは、 インスタンスを生成した後に実行させること(実行させる目的)も はっきりしていないということになります。 (前回の例では、メニュー項目を実行させる目的で、インスタンスを生成したわけです。) ほとんどの場合、クラスをインスタンス化するには、何らかの目的があるはずですから、 その目的をグループ化したクラス等で受ければいいわけです。 あまり考えられませんが、インスタンス化するクラスが、 ・Stringだったらlength()を実行 ・ArrayListだったらsize()を実行 などのように、全く関係ないクラスがインスタンス化される可能性がある場合は、 Object obj = Class.forName(className).newInstance(); のように、Object型で受ければOKです。 その後、 if(obj instanceof String){  String s = (String)obj;  System.out.println("length=" + s.length() ); }else if(obj instanceof ArrayList){  ArrayList list = (ArrayList)obj;  System.out.println("size=" + list.size() ); } のようになります。 ですから、受けるクラス名が動的に指定されなくても問題はありません。

  • kacchann
  • ベストアンサー率58% (347/594)
回答No.4

>リターンを受けるクラス名が、動的に指定されていないため、具体的な利用方法が分かりませんでした >Class.forNameのパラメータが動的に指定できるとき、 受け入れるクラス名を動的に指定できないのであれば、結果的に動的にクラスを生成できないのでは Fooというクラスの変数 Foo f; があった場合、fに代入できるインスタンスは 「Fooクラスのインスタンス」 のみならず、 「『Fooを継承しているサブクラス』のインスタンスすべて」 が代入可能。(スーパークラス型への代入) また、Fooというのが(クラス名でなく)インターフェース名だった場合、 Foo f; なる変数fに代入できるのは、 「『インターフェースFooをインプリメント(実装)しているクラス』のインスタンスすべて」 が代入可能。(インタフェース型への代入) ---- つまり、上記の2通りのいずれかを満たしていれば、 代入先の変数の「型」の名前が固定されていても、 そこに代入するインスタンス(のクラス)は動的に「選べる」ことになる。 Javaの「多態(ポリモーフィズム)」について調べみよう。 この辺の話をわかりやすく解説しているはずだ。 Javaプログラミングにおける超基本事項であり、 最重要事項の1つでもある。 ------ ↓実験すべし import java.awt.*; public class Test {  public static void main(String[] args) {   String s;   if ("a".equals(args[0])) {    s = "java.awt.Rectangle";   } else if ("b".equals(args[0])) {    s = "java.awt.Frame";   }else {    s = "java.awt.Point";   }      Object o=null;   try {    o = Class.forName(s).newInstance();//※   }catch(Exception e) {e.printStackTrace();}   System.out.println(o);  } }

参考URL:
http://msugai.fc2web.com/java/polymorphism.html
chachax
質問者

お礼

有難うございました。 urlの紹介もいただき有効活用させていただきます。

  • lawson
  • ベストアンサー率44% (29/65)
回答No.3

思いつく例を 2点挙げます まず、1つ目 No1で例にあげられたドライバーのクラス名が プロパティーファイルに記述されている ようなケースでは、 Class.forNameを使って動的にする以外に 方法がない。 2つ目 抽象クラス ItemFactoryの中で this.getClass().getName() で得られる自身のクラス名の 「Factory」という文言を「Product」 に変えたクラスのインスタンスを Class.forName( を使ったやり方で 生成する コードがあるメソッドがあったとして。 継承クラス ItemFactoryAクラスにおけるそのメソッドの 挙動としては、 ItemProductAクラスのインスタンスを 生成する。 継承クラス ItemFactoryBクラスにおけるそのメソッドの 挙動としては、 ItemProductBクラスのインスタンスを 生成する。 なぜなら、 this.getClass().getName() の部分の thisは実行時の ItemFactoryAや ItemFactoryBの インスタンスだから。

chachax
質問者

お礼

Menuにクラス名を登録しておき、指定されたMenuのクラスをスタートするようなことを考えていました。 お教えを参考にさせていただきます。 有難うございました。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

まず、確認をしておきましょう。 Class.forName("Hoge").newInstance(); というのは、 Class cls = Class.forName("Hoge"); Hoge hg = (Hoge)cls.newInstance(); と同じ意味で、さらに Hoge hg = new Hoge(); と同じ意味です。 また、インスタンス生成時にタイプを限定したくないのであれば、 Class cls = Class.forName("Hoge"); Object hg = cls.newInstance(); となります。 指定したオブジェクトのクラス名を知りたいなら、 Hoge hg = new Hoge(); Class cls = hg.getClass(); System.out.println(cls.getName()); でOKです。 *何が知りたいのかよくわからなかったので、  いっぱい書いてしまいました。

chachax
質問者

お礼

インスタンス生成時にタイプを限定しない方法を知りたく思っていましたので、助かりました。 有難うございました。

  • jun-1
  • ベストアンサー率29% (18/61)
回答No.1

java.sql.Driverクラスなんかのインスタンスを生成 する場合なんかによく使ったりします。 ・ ・ OracleDriver driver = (Driver)Class.forName("oracle.jdbc.driver.OracleDriver").newInstnace(); ・ ・ そのほかにも動的にクラスが生成できるため、FactoryMethod パターンなんかにも適応できると思います。

chachax
質問者

補足

Class.forNameのパラメータが動的に指定できるとき、 受け入れるクラス名を動的に指定できないのであれば、結果的に動的にクラスを生成できないのではと考えています。 例えば、次のような使い方が出来ないのかお教えいただきたいのです。よろしくご教示下さい。 String strClassW; String strClassA "ClassA"; String strClassB "ClassB"; if (arg[0].equals("a")) {   strClassW = strClassA; } else {   strClassW = strClassB; } 以下の表記はjavaで許されるものではないと思いますが、 Class(strClassW) class = Class.forName(strClassW).newInstance(); System.out.println(class.toString());  

関連するQ&A

  • JDBCドライバーのロードに関して

    参考書やwebページのソースコードにJDBCドライバーのロードのときに、Class.forName("...")と書いているものと、Class.forName("...").newInstance()と書いているものがあります。[...部分は省略]この二つのコードは、どこが違うのでしょうか。また、Sunmicroのホームページで、forNameメソッドは、"指定された文字列名を持つクラスまたはインタフェースに関連付けられた、Class オブジェクトを返します。"と、newInstanceメソッドは、"この Class オブジェクトが表すクラスの新しいインスタンスを生成します。"と書かれていますが、どうしてこれで、JDBCドライバーがロードされるのですか?また、初歩的な質問ですが、JDBCドライバーがロードされるというのは、どうゆうことですか?教えてください。

    • ベストアンサー
    • Java
  • Class.forName("org.postgresql.Driver")の意味

    JDBCを使って、PostgreSQL を利用する場合、 まず最初に、Class.forName("org.postgresql.Driver")というのを使いますよね。 この、Class.forName(String str)メソッドは、str にある、クラスを初期化すると仕様書には書いてます。 (Class.forName("org.postgresql.Driver")).newInstance() を実行して、org.postgresql.Driver.class のコンストラクタを実行するというのなら、意味はわかるのですが、、、 ただClass.forName("org.postgresql.Driver")の命令だけを使ってなんの意味があるのでしょうか? 意味不明で困っています。どうか、よろしくお願い致します。

    • ベストアンサー
    • Java
  • JDBC ドライバーのロードの方法について

    すみませんが、どなたか教えていただけないでしょうか。 JDBCを使ってデータベースにアクセスしようとする場合に、まずドライバーのロードが必要ですが、 1.Class.forName("ドライバー名"); 2.Class.forName("ドライバー名").newInstance(); 1の方法と2の方法の違いは何かあるのでしょうか?今まで私は1の方法を使っていたのですが、2の方法があると知り、どのようなときに使うものなのかわかりません。このようなときにはこっちを使う、というようなルールや目安などありましたら、教えていただけますでしょうか。 ちなみに私は、データベースはDB2を使っています。 ↓また、以前に似たような(?)質問も見受けられたのですが、私にはちょっと難しくて理解できませんでした… http://okweb.jp/kotaeru.php3?q=642489 どうぞよろしくお願いいたします。

    • ベストアンサー
    • Java
  • サブクラスで.newInstance()でインスタンス化できない

    以下のようにClass.forNameで取得したクラスをインスタンス化 しようとしていますが、できません サブクラスは.newInstance()でインスタンス化できないのでしょうか? 代替の方法はありますか? ーーーーーーーーーーーーーーーー public class test4121 { public static void main(String[] args) throws Throwable { new test4121(); } public test4121() throws Throwable { //これは実行できるが test4121_2 test = new test4121_2(); //これはできない Class.forName("test4121$test4121_2").newInstance(); } class test4121_2{ } } ーーーーーーーーーーーーーーーー

  • 指定されたクラスの継承元の確認方法

    Class cls = Class.forName("extendsClass"); Object obj = cls.newInstance(); if (obj instanceof AbstractClass) {   System.out.println("継承してた");   ((AbstractClass)obj).method(); } こんなことをして、objのクラスがAbstractClassを継承しているという ことは確認することが出来たのですが、これはやはり継承しているか どうかを確認する為にインスタンス化を行っています。 指定された名称のクラスが、特定のクラスを継承していた場合に限り、 その名称のクラスをインスタンス化する、 という流れは行えないのでしょうか?

    • ベストアンサー
    • Java
  • CSS内で呼び出してる画像に対して、class属性をつけたい

    CSS内で呼び出してる画像に対して、class属性をつけたい お世話になります、CSSに関して下記のようなことは可能なのでしょうか。 とあるライブリにimgタグにclass属性を指定して使用するものがありました。 例:<img src="image.gif" class="○○"/> (クラスを指定すると画像にエフェクトがかかる) これをcssで下記のように呼び出している画像に対して適用することは可能でしょうか。 [cssファイル] #bkg .opt1 { background: url('画像のパス'); } [html] //こんな感じで呼んでいる <li class="bkg opt1"><span>image</span></li> CSS内でクラス指定ができないものかと色々試してみたもののうまくいきません・・ 適用方法、ヒント等教えていただけますでしょうか よろしくお願いします

  • 時間のフォーマット

    数値を時間(HH:MM:SSやAM/PM HH:MM:SS)にフォーマットしたいのですが、どのようにコーディングすればよいのでしょうか? SimpleDateFormatクラスを使用して試みているのですが、 どうしてもできません・・・ 例)131214 → PM 1:12:14

    • ベストアンサー
    • Java
  • 内部クラスのインスタンスを動的に取得したい

    class test {   public test(String str){     try{       Class c = Class.forName("test$TESTSUB" + str);       c.newInstance();  // ココでエラー     }catch(Exception e){       e.printStackTrace();     }   }   public static void main(String[] args){     new test(args[0]);   }   class TESTSUB1 {     public TESTSUB1(){       System.out.println("# " + toString());     }   }   class TESTSUB2 {     public TESTSUB2(){       System.out.println("# " + toString());     }   } } 上記のようなコードにより、内部クラスのインスタンスを 動的に得たいと思っていますが、エラーとなってしまいます。 エラー回避方法、または他にいい方法がありましたら、 ご教示のほどよろしくお願いいたします。

    • ベストアンサー
    • Java
  • python: 例外classの書き方

    pythonで独自の例外classの書き方をチュートリアルで見ていて気づいたことがあります 次のような記載をみつけました class wexal(Exception):  pass 質問の都合上次のように書き換えます class abcde(Exception): 質問: 1)独自の例外クラスの書き方は、(Exception)と記載すれば、abcdeのように名称はなんでも指定できると考えてよいでしょうか 2) Guido van Rossum さん著書のチュートリアル本(ISBN-13 ‏ : ‎ 978-4873119359)をみていると、class の記載の後の名称の最初の文字は大文字になっているものが多くあります  上記で abcdeの部分は、Abcdeでなくても作法上問題ないのでしょうか。つまり(Exception)を記述するときは、最初の文字を大文字にする必要は作法上はないのでしょうか 他の例外の処理については、今回は求めていません。独自例外classの書き方についてのみ質問しています。 【回答上のご注意】 回答は、解答(答え)を求めています わたしはプログラマーではないので、昭和的な「自分で考えろ」的なものは求めていません わからなければ答えない自由もあなたにはあります 不明点があれば説明いたします

  • インスタンス化の"class"の有無による違い

    インスタンス化のときに、以下の(1)と(2)の「class」の有無によって何が変わるのかわからないです。教えて下さい。 (1)class [クラス名] [オブジェクト名]; (2)[クラス名] [オブジェクト名]; 以下に例としてコードとその出力結果を示します。 コード----------------------------------------------------- #include <iostream> using namespace std; class Property { public: double mass; }; int main( ) { class Property material_one; Property material_two; material_one.mass=5.0; material_two.mass=3.0; cout << material_one.mass << "\n"; cout << material_two.mass << "\n"; return 0; } ------------------------------------------------------------- 出力結果-------------------------------------------------- 5 3 -------------------------------------------------------------

専門家に質問してみよう