1

私はJavaで次のことをしようとしています:

文字列のコレクション (1 から 10 000 の間) があり、各文字列には、クラスの同じ抽象メソッドの異なるメソッド本体 (Java コードで記述されています) が含まれています。例えば:

string1= "int a=1;" 
string2="System.out.println(\"HelloWorld\");"
...

各文字列は、次の抽象メソッドの実装である可能性があります。

abstract class FOO{
    public abstract void doSomething();
}

文字列ごとに、使用する FOO のインスタンスを生成したいと思います。

何が最善の方法なのかよくわかりません。ウェブを検索して、次の提案を思いつきました。

  • Java 6 コンパイラ API を使用して .class ファイルを生成し、それらをロードします。
  • cglib のようなバイトコード操作ライブラリを使用して、コンパイル コードを変更します。

これらは少し複雑に見えるので、他に提案はありますか(少なくとも私には)...

ご協力いただきありがとうございます

編集:

私は自分の問題について間違った方向に進んでいる可能性があります。これが私が最終的に達成しようとしているものです:

ツリー内のノードを表すインターフェースがあります

public  interface Node{
    public <T> void process(T input);

/* ... 私の問題とは関係のない他の方法 ...*/ }

T のインスタンスをノードに提供すると、それに対して何らかの処理が行われ (ノードの他のメソッドへのアクセスが必要になる場合があります)、それが子ノードに渡されます。

問題は(プログラムの仕様)です。プログラムは、そのメソッド本体を含むテキストファイルからノードを読み取り、構築します(本体はJavaにあります)。次に、ツリーを構築して返します。

これを行うには、テキスト ファイルで提供されているメソッドごとに Node の実装を何らかの方法で生成する必要があるという印象を受けました。私が間違っているかもしれませんし、もっと良い方法があるかもしれません...

4

1 に答える 1

3

おそらくあなたが望むのはBeanShellです

BeanShell は、Java で記述されたオブジェクト スクリプト言語機能を備えた、小さくて無料の組み込み可能な Java ソース インタープリターです。BeanShell は、標準の Java 構文を動的に実行し、Perl や JavaScript のような緩い型、コマンド、メソッド クロージャーなどの一般的なスクリプト作成の便利さで拡張します。

BeanShell をインタラクティブに使用して、Java の実験やデバッグを行ったり、新しい方法でアプリケーションを拡張したりできます。Scripting Java は、ラピッド プロトタイピング、ユーザー スクリプト拡張、ルール エンジン、構成、テスト、動的展開、組み込みシステム、さらには Java 教育など、さまざまなアプリケーションに役立ちます。

BeanShell は小さく、組み込み可能であるため、Java アプリケーションから BeanShell を呼び出して、実行時に Java コードを動的に実行したり、アプリケーションに拡張性を提供したりできます。あるいは、スタンドアロンの BeanShell スクリプトを使用して Java アプリケーションを操作することもできます。Java オブジェクトと API を動的に操作します。BeanShell は Java で記述され、アプリケーションと同じ VM で実行されるため、「ライブ」オブジェクトへの参照をスクリプトに自由に渡し、それらを結果として返すことができます。

つまり、BeanShell は動的に解釈される Java に加えて、スクリプト言語と柔軟な環境がすべて 1 つのクリーンなパッケージにまとめられています。

機能の概要

  • 完全な Java 構文、Java コード フラグメント、および緩やかに型付けされた Java と追加のスクリプトの便利さの動的実行。
  • すべての Java オブジェクトと API への透過的なアクセス。
  • コマンド ライン、コンソール、アプレット、リモート セッション サーバーの 4 つのモードで実行されます。
  • ほとんどの機能のクラスローダーまたはバイトコード生成なしで、セキュリティが制限された環境で動作できます。
  • インタプリタは小さな ~150K jar ファイルです。
  • ピュアジャバ。
  • それは無料です!!

別の方法は、メモリ内でコンパイルして現在の ClassLoader にロードするように、Compiler API をラップする、私が作成したライブラリを使用することです (デフォルト)。

http://sourceforge.net/projects/essence/files/Essence%20Java%20Config.%20Files/Essence%20JCF%201.02/

http://vanillajava.blogspot.co.uk/2010/11/more-uses-for-dynamic-code-in-java.html

// this writes the file to disk only when debugging is enabled.
CachedCompiler cc = CompilerUtils.DEBUGGING ?
        new CachedCompiler(new File(parent, "src/test/java"), new File(parent, "target/compiled")) :
        CompilerUtils.CACHED_COMPILER;

String text = "generated test " + new Date();
Class fooBarTeeClass = cc.loadFromJava("eg.FooBarTee", "package eg;\n" +
    '\n' +
    "import eg.components.BarImpl;\n" +
    "import eg.components.TeeImpl;\n" +
    "import eg.components.Foo;\n" +
    '\n' +
    "public class FooBarTee{\n" +
    "    public final String name;\n" +
    "    public final TeeImpl tee;\n" +
    "    public final BarImpl bar;\n" +
    "    public final BarImpl copy;\n" +
    "    public final Foo foo;\n" +
    '\n' +
    "    public FooBarTee(String name) {\n" +
    "        // when viewing this file, ensure it is synchronised with the copy on disk.\n" +
    "        System.out.println(\"" + text + "\");\n" +
    "        this.name = name;\n" +
    '\n' +
    "        tee = new TeeImpl(\"test\");\n" +
    '\n' +
    "        bar = new BarImpl(tee, 55);\n" +
    '\n' +
    "        copy = new BarImpl(tee, 555);\n" +
    '\n' +
    "        // you should see the current date here after synchronisation.\n" +
    "        foo = new Foo(bar, copy, \"" + text + "\", 5);\n" +
    "    }\n" +
    '\n' +
    "    public void start() {\n" +
    "    }\n" +
    '\n' +
    "    public void stop() {\n" +
    "    }\n" +
    '\n' +
    "    public void close() {\n" +
    "        stop();\n" +
    '\n' +
    "    }\n" +
    "}\n");

// add a debug break point here and step into this method.
FooBarTee fooBarTee = new FooBarTee("test foo bar tee");
Foo foo = fooBarTee.foo;
assertNotNull(foo);
assertEquals(text, foo.s);
于 2012-10-30T12:56:49.797 に答える