1

Javaクラスを自己インスタンス化するにはどうすればよいですか?クラスファイル以外のファイルは使用しないでください。また、NAME変数を初期化した行の後、コンパイル時にクラスの名前がわからないとします。

例:

public class Foo implements Bar {
    public static final String NAME = "Foo";

    private void instantiate()  {
        Bar baz = (Bar)Class.forName(NAME).newInstance();
    }
    //...
}

と呼ばれる別のファイルが必要なため、間違っていますBar.java。そのはず:

public class Foo {
    /*
    Instantiate self...
    */
}

私はこのプログラミングチャレンジのウェブサイトに参加しました。そこでは、問題ごとに1つのファイルしか提出できません。チャレンジに使用するすべてのクラスのテンプレートクラスを作成したいと思います。だから、私が心に留めているのは、これを行うということです:

public class Foo {
    public static final String NAME = "Foo";


    public static void main (String[] args) throws IOException {
        //Instantiate self and call launch(args)
        Foo foo = new Foo();
        foo.launch(args);
        System.exit(0);
    }

    public void launch(String[] args) {
        //...Do actual code here
    }
}

クラス名とNAME変数のみを変更したいので、テンプレートクラスを使用するたびにクラスをインスタンス化する方法を変更する必要はありません。私が持っている現在の設定では、行を編集する必要があります:Foo foo = new Foo();そしておそらくその下の行。

launch()また、なぜ私が呼び出して、mainメソッド内ですべてを実行しない必要があるのか​​疑問に思われるかもしれません。これは、Javaのインストラクターから得たものです。また、メソッド内で非静的メソッドを使用できないためmain()です。

4

7 に答える 7

1

メッセージを編集し、さらに情報を追加しました。それは良い。これで、問題はより明確になりました。あなたは実際にファクトリパターンを探しています。

public abstract class Batch {
    public static void main(String[] args) throws Exception {
        Batch batch = (Batch) Class.forName(args[0]).newInstance();
        batch.run();
    }

    abstract void run();
}

class Foo extends Batch {
    public void run() {
        System.out.println("Executing Foo");
    }
}

class Bar extends Batch {
    public void run() {
        System.out.println("Executing Bar");
    }
}

最初の引数は明らかにクラス名です。お役に立てれば。

于 2009-11-04T16:48:27.737 に答える
1

複数のメソッドを呼び出さないのに、なぜ参照を保存するのでしょうか?

public class Foo {
  public static void main(String[] args){
    new Foo().launch(args);
  }
  public void launch(String[] args){
    //...
  }
}

ここで、問題ごとにファイルを変更するために必要なことは、クラス ヘッダーとnew句の 2 行を変更することだけです。簡単!

于 2010-08-20T14:55:23.703 に答える
1

If you "implement" anything, you NEED to have an interface defined. Either you import one that already exists, or you have to create it. Either way, if it's a public class (abstract or not) or an interface, it MUST be defined in a separate file. Unlike C++, this is a java requirement.

If:

public class Foo implements Bar { 
} 

then your project must be comprised of at least:

Foo.java
Bar.java 

Period. No ifs/ands/buts.

But if you absolutely must have only one file in your project, you'll have to get a byte-code generator and build your class and interfaces dynamically at runtime.

The real question is: what are you trying to accomplish? If it's a Singleton/Factory, others have answered that already. If it's to reduce the number of compilation units, then you're out of luck. Java enforces the requirement that you have to do it this way.

EDIT AFTER AUTHOR UPDATES:

Java lets you do things like so:

Foo.java:

public class Foo { 
  public static void main(String[] args) { 
    Bar bar = new Bar(); 
  }
}
class Bar { 
   int bar_var; 
   Snafu fu = new Snafu(); 

   public Bar() {  } 
   public int getBarVar() { return bar_var; } 
} 
class Snafu { 
   int var; 
   public Snafu() { } 
}

.... 

Which would accomplish what you want to achieve.

于 2009-11-04T16:27:15.593 に答える
0

ここでは、Javaのネストされた/内部クラスについて聞いたことがありませんか?それらは、約9年前に新しくなったJDK1.2から存在しています。

public class Main {
    public static void main(String[] args) {
        Bar b = new Foo();
        b.doSomethingExciting();
    }
    interface Bar {
        void doSomethingExciting();
    }
    static class Foo implements Bar {
        public void doSomethingExciting() {
            System.out.println("Boo!");
        }
    }
}

含むクラスをモジュールとして使用し、ネストされたクラスとインターフェイスの任意のコレクションを含めることで、クラスを本質的に任意の深さにネストできます。を含めることによりmain(String[])、プログラムを開始できるエントリポイントを提供します。

このアプローチにより、任意の数のクラスファイルを生成できる1つのソースファイルが得られます。ネストされたクラスはすべて一意の名前になります(トップレベルに複数の非公開クラスを含めるハックとは異なります)。

于 2009-11-04T19:37:20.280 に答える
0

コンストラクターを呼び出すクラスmain内のメソッドが必要です。Foo

public static void main(String[] args) {
    Foo f = new Foo(); //the new syntax uses a Constructor, not reflection
    //etc

次に、実行可能ファイルを介してクラスを実行javaできます (メイン メソッドが呼び出されます)。

$> java mypackage.Foo

Barインターフェイスの実装を選択した理由がわかりません。これはあなたの質問からは不要のようです。

于 2009-11-04T16:16:52.980 に答える
0

どうですか?

public class Foo {

    private void instantiate()  {
        Foo foo = Foo.class.newInstance();
    }
    //...
}
于 2009-11-04T16:20:08.213 に答える
0

メインメソッドでそれを行うには:

public class Foo implements Bar {
    public static final String NAME = "Foo";

    public static void main(String[] args) {
        Foo f = new Foo();
    }

または初期化子として:

public class Foo implements Bar {
    public static final String NAME = "Foo";
    private static final instance = new Foo();

    private void getInstance()  {
        return instance;
    }
}
于 2009-11-04T16:20:21.593 に答える