アプリ版:「スタンプのみでお礼する」機能のリリースについて

Class.forName("Hogehoge");は
動的にクラス(この例では"Hogehoge")をロードする場合に使用するとの説明が当Q&Aに記載されていましたが、次のコーディング例が有りました。

Hogehoge hh = Class.forName("Hogehoge").newInstance();

この例では、リターンを受けるクラス名が、動的に指定されていないため、具体的な利用方法が分かりませんでした。

よろしく、ご教示いただければ幸甚です。

A 回答 (6件)

#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();

となります。
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/07/07 21:00

#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() );
}

のようになります。


ですから、受けるクラス名が動的に指定されなくても問題はありません。
    • good
    • 0

>リターンを受けるクラス名が、動的に指定されていないため、具体的な利用方法が分かりませんでした



>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
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/07/07 21:07

思いつく例を


2点挙げます

まず、1つ目
No1で例にあげられたドライバーのクラス名が
プロパティーファイルに記述されている
ようなケースでは、
Class.forNameを使って動的にする以外に
方法がない。


2つ目

抽象クラス
ItemFactoryの中で
this.getClass().getName()
で得られる自身のクラス名の
「Factory」という文言を「Product」
に変えたクラスのインスタンスを
Class.forName( を使ったやり方で
生成する
コードがあるメソッドがあったとして。

継承クラス
ItemFactoryAクラスにおけるそのメソッドの
挙動としては、
ItemProductAクラスのインスタンスを
生成する。

継承クラス
ItemFactoryBクラスにおけるそのメソッドの
挙動としては、
ItemProductBクラスのインスタンスを
生成する。

なぜなら、
this.getClass().getName()
の部分の
thisは実行時の
ItemFactoryAや
ItemFactoryBの
インスタンスだから。
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/07/06 19:00

まず、確認をしておきましょう。



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です。


*何が知りたいのかよくわからなかったので、
 いっぱい書いてしまいました。
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/07/06 18:49

java.sql.Driverクラスなんかのインスタンスを生成


する場合なんかによく使ったりします。



OracleDriver driver = (Driver)Class.forName("oracle.jdbc.driver.OracleDriver").newInstnace();



そのほかにも動的にクラスが生成できるため、FactoryMethod
パターンなんかにも適応できると思います。

この回答への補足

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());  

補足日時:2004/07/05 21:53
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!