2009-07-28 57 views
4

ユーザーからの入力を保持するために変数を生成する必要があるとしましょう(それらの数はわかりません)。 Arrayを使用せずにArrayList(および他の種類のリストやマップ)を使用しないと、Stringという変数をX回(String var001String var002String var003など)の名前で生成することができますか?はいの場合は、サンプルコードを入力してください。Javaで変数名を動的に生成する方法はありますか?

+5

の助けを借りて、実行時にオブジェクトを取得

// ...あなたが何を意味するのか - 「がいくつあるか分からない」は?あなたはいつ知っていますか?実行時に?とにかく、これは実際にコレクションクラスの仕事のように見えます。なぜあなたはそれらを使用できないのですか?あなたの問題についてもっと教えてください。 –

+0

私はそれが奇妙な要求だと知っていますが、これは私たちの教授がテーブルに載せている挑戦的な問題です。だから私は、その使いやすさにかかわらず、それを行う可能性についてもっと心配しています! 私のグループが見つけたこの周りの唯一のトリックは、この問題に関して既に提案されている「Markus Lausberg」です。 –

+2

あなたの教授がスタックオーバーフローを読んでいないことを願っています!彼/彼女の名前は何ですか? –

答えて

2

は私が実装され、多くのハードルなしで簡単に私の解決策を修正するために私を助けてきた方法です。

//配列リスト

List accountList = new ArrayList(); 




for(int k=0;k < counter;k++){ 
     accountList.add(k, (String)flowCtx.getValueAt("transitId"+m)); 
} 

反復処理ループを作成し、インデックス付きのArrayListにオブジェクトを追加します。これは非常に奇妙な要求であるインデックス

String a = accountList.get(i)); 
+1

ここでflowCtxとは何ですか? – Yatin

2

あなたは

VAR0、VAR1、VAR2という名前の変数を生成し、あなたのコードでそれらを使いたいわけ。あなたは VAR [0]、VAR [1]、VARを使用する場合

は違いは何である[2]、.....

しかし

あなたは動的にJavaクラスを生成することができます実行時に通常のコードで使用しているインタフェースを実装します。次に、コンパイラ(たとえばJanino)を使用してこのクラスをコンパイルし、実行時にクラスをロードします。あなたがクラスを動的に作成したよりも。

しかし、これがあなたの用途に必要かどうかは不思議です。あなたはこれが不可能であるが、これは完璧です。このexample from here

​​
1

のようにJavaで使用することができます。このパラメータが、動的な引数を使用しているユースケースれる私は今いけない

EDIT

いずれかのJavaコレクションを使用するための候補です。実行時に、それのサイズを変更することができ

String[] arr = new String[RUNTIME_SIZE]; 

またはリスト:そのような

List list = new ArrayList<String>(); 
+1

記録のために、PHPで可能です。マニュアルの変数変数を参照してください。 –

+1

申し訳ありません。この質問のPHPタグ... –

2

命名変数は非常に1980年っぽい見え

は、動的に割り当てられた配列を使用しますか。意味オブジェクト指向プログラミング。 それでは、生活のためのソフトウェアを作ってしまったら - これをしないでください。

しかし、宿題のようですので、...私たちは、Javaの名前の変数の話をしているとき

、我々はコンパイル何かを意味します。いくつかのスクリプト言語とは異なり、これをJavaで簡単に行う方法はありません。

Markus Lausbergのように、ランタイムコンパイルされたクラスを使用することをお勧めします。
または、Java Scripting APIを不正行為させて使用し、スクリプト言語を使用してください。これにより、実行時にコードを(String内で)作成することができます。

+0

JavaスクリプトAPIは非常に興味深いです:) 新しい情報ありがとう –

2

私はあなたにもそのバイトコードでクラスを構築することができ、実行時にJavaクラスを生成するか、多分変数を生成するためにBeanshellのようないくつかのスクリプトエンジンを使用することができると思います。しかし、私はあなたのコードでその変数を使用する方法を見ることができません、あなたはまた、その変数で動作するようにコードを作成する必要があります、またはその反射を使用して...

素朴なソリューション:
それぞれのgetterとvar999へvar000からすべての変数を持つクラスを作成します...が、それは、動的に本当にありません!

アレイ、ArrayListを(およびリストやマップの 他の種類)を使用せず
3

これらの名前のファイルを作成します。あなたの教授のためにうまくいくことを願っています。

またはJavaスクリプトAPIは、前に述べた使用:

ScriptEngineManager manager = new ScriptEngineManager(); 
ScriptEngine engine = manager.getEngineByName("JavaScript"); 

engine.put("x", "hello"); // you can add any variable here 
// print global variable "x" 
engine.eval("println(x);"); 
// the above line prints "hello" 

EDITは

は、内部で、これは彼らが(プロパティファイル、環境設定API、またはDOMツリーと地図:)同じ使用されますように思えますベクトルを使用して)。あなたの教授がとても嫌な人なら、ファイルを使ってください。

+0

ありがとうございます :) –

2

私は、これはまだ答え見ていないので、私はそれのために行きますよ。 Javaソースコードを書き出すだけのプログラムを書く。そのほとんどはテンプレートであり、あなたが望むように多くの "string UserString003"型変数を書き込むループを持つだけです。

はい、これは恐ろしいです。しかし、あなたが言ったように、それは宿題のための概念的な挑戦の問題です。だから誰も "良い"コードでこれを間違っている限り、問題を解決するかもしれません。

4

実際にのようなことをしたい場合は、ASMまたは他のライブラリを使用してバイトコード生成を行うことができます。ここで

は「var99」にフィールド「VAR0」を含む「foo.bar.ClassWithFields」という名前のクラスを生成するコードです。もちろん、これらのフィールドにアクセスするためのリフレクション以外の方法はありません。コンパイル時には存在せず、Javaは静的に型指定された言語なのでです。

import org.objectweb.asm.*; 
import static org.objectweb.asm.Opcodes.*; 

import java.lang.reflect.Field; 

public class GeneratedFieldsExperiment { 

    public static byte[] generateClassWithFields(int fieldCount) throws Exception { 
     ClassWriter cw = new ClassWriter(0); 
     FieldVisitor fv; 
     MethodVisitor mv; 
     AnnotationVisitor av0; 

     cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "foo/bar/ClassWithFields", null, "java/lang/Object", null); 

     for (int i = 0; i < fieldCount; i++) { 
      fv = cw.visitField(ACC_PUBLIC, "var" + i, "Ljava/lang/String;", null, null); 
      fv.visitEnd(); 
     } 
     { 
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 
      mv.visitCode(); 
      mv.visitVarInsn(ALOAD, 0); 
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); 
      mv.visitInsn(RETURN); 
      mv.visitMaxs(1, 1); 
      mv.visitEnd(); 
     } 
     cw.visitEnd(); 

     return cw.toByteArray(); 
    } 

    public static void main(String[] args) throws Exception { 
     MyClassLoader loader = new MyClassLoader(); 
     Class<?> c = loader.defineClass("foo.bar.ClassWithFields", generateClassWithFields(100)); 

     System.out.println(c); 
     System.out.println("Fields:"); 
     for (Field field : c.getFields()) { 
      System.out.println(field); 
     } 
    } 

    private static class MyClassLoader extends ClassLoader { 
     public Class<?> defineClass(String name, byte[] b) { 
      return defineClass(name, b, 0, b.length); 
     } 
    } 
} 
+0

コードのいくつかのコメントは本当に役立つでしょう:)ありがとう! –

+2

それはASMを使用していますライブラリを使用してクラスを生成する - バイト配列は、Javaコンパイラが生成する.classファイルと同じ形式です。その後、JVMにロードします。カスタムクラスローダーを作成します。 ASMはJavaバイトコードレベル(アセンブリコードに似ています)で動作しますので、上記のコードを理解するには、最初にいくつかのJavaバイトコードを学習する必要があります(ASMのドキュメントはそれに適しています:http://download.forge.objectweb.org/asm/ asm-guide.pdf)を参照してください。その他のバイトコード操作ライブラリは、純粋なバイトコードよりも高いレベルであるため、ASMよりも使用する方が簡単です。私はJavassistがそのような図書館の1つだと思う。 –

2

あなたの教授は、機能(Variable variables)上でPHP-バイアスされているので、それがJavaで可能であったならば、彼が考えていたように見えます。

私は個人的にはない、あなたが提案している方法で、これが可能であるとは思いません。実行可能なことは、より強力なリフレクションメカニズムを作成するために、Javassistのようなツールを使用して、実行時にクラスを生成することです。したがって、実行時に必要な変数(string1、string2など)を持つクラスを作成できます。

しかし、Variable variablesは、不正なコードにつながる本当に悪い技術であることを忘れないでください。非常に少数のケースでは有用かもしれませんが、私は本当にそれをお勧めしません。続き

関連する問題