は離れたところにございまを生成す変数名を動的にJava?
-
19-09-2019 - |
質問
いまを生成しなければならない変数保持部から入力したユーザーがわからないのが多い。を使用せずに Array
, ArrayList
(その他の種類のリスト地図で自分のコード生(せい) String
変数Xの時代といった名前(String var001
, String var002
, String var003
, など)?ご提供のサンプルコード。
解決
に続いて、私が実装され、多くのハードルなしで簡単に私の解決策を修正するために私を助けてきた方法です。
//配列リストの作成
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));
他のヒント
は、を使用してバイトコード生成を通してそれを行うことができます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);
}
}
}
(アレイ、のArrayListを使用することなく、かつ リストやマップの他の種類の)
これらの名前のファイルを作成します。それはあなたの教授のために働くことを願っています。
以前に言及した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"
編集
内部でこのプロパティファイル、環境設定API、またはDOMツリー(彼らはベクトルを使用している)で地図:)同じを使用するように思えます。あなたの教授がとてもうるさいですのであれば、ファイルを使用します。
私は、これはまだ答え見ていないので、私はそれのために行きますよ。単にJavaソースコードを書き込むプログラムを書きます。そのほとんどは、テンプレート可能性があり、そして、あなたはちょうどあなたが好きなだけ「の文字列UserString003」型の変数を記述したループを持つことになります。
はい、これは恐ろしいです。しかし、あなたが言ったように、それは、宿題のためにそう限り誰の過ちとして、この「良い」のコードのための概念的な挑戦の問題だ、それは問題を解決する可能性があります。
は、非常に1980っぽい見えるような変数の命名。前のオブジェクト指向プログラミングを意味。 あなたは生活のためのソフトウェアを構築するのであれば - 。これをしない
しかし、それは宿題のようですので、...
我々はJavaで名前の変数の話をしているときに、我々は、コンパイルされています何かを意味します。いくつかのスクリプト言語とは異なり、Javaでこれを行う簡単な方法はありません。
だから、マルクスLausbergが提案のようにどちらかのあなたは、ランタイムコンパイル済みのクラスを使用します。
それとも、カンニングとのJavaスクリプトAPIを使用しますとスクリプト言語を使用しています。そのようにあなたは、実行時に(文字列で)コードを作成することができます。
私は、実行時にJavaクラスを生成するか、多分生成する BeanShellののようないくつかのスクリプトエンジンを使用することができると思います変数は、あなたもそのバイトコードでクラスを構築することができます。しかし、私はあなたのコード内の変数は、あなたもその変数で動作、またはそのためにリフレクションを使用するコードを作成する必要があることをどのように使用するかを見ることができない...
の素朴な解決策:
それぞれにゲッターとvar999へvar000からすべての変数を持つクラスを作成します...しかし、それは本当に、動的ではありません!の
あなたの教授は機能上のPHP-バイアスされているように見えます(可変変数を)ので、それはJavaで可能であったならば、彼は考えていた。
私は個人的にはない、あなたが提案している方法で、これが可能であるとは思いません。何行うことができることは Javassistのようなツールを使用して、実行時にクラスの生成でありますより強力な反射機構を作ることを。だから、実行時にしたい変数(文字列1、文字列2、など)を持つクラスを作成することができます。
しかし、変数変数ということを忘れないでくださいする不正なコードにつながる本当に悪い技術です。それは非常にまれなケースで役に立つかもしれないが、私は実際にそれをお勧めしません。
を利用することを生成する変数の名前
var0,var1,var2用のコードです。
何か違いはあるときに使用 var[0]、[1]、[2],.....
が
生成することができるJavaクラスを動的に実行時にを実装するインターフェースに使用通常のコードです。そのコンパイルこのクラスを使用しコンパイラ(例えばJanino)負荷のクラスを行います。より作成したクラスを動的に
そして、もうひとつからする必要があることがわかりご利用.
編集
あまりないと思います現する利用法を使用このパラメータが動的引数で使用できるJavaこのような 例はこちらから
// calculate average
public static double average( double... numbers )
{
double total = 0.0; // initialize total
// calculate total using the enhanced for statement
for ( double d : numbers )
total += d;
return total / numbers.length;
} // end method average
これは不可能ですが、これはJavaのコレクションの一つを使用するための完璧な候補である。
動的に割り当てられた配列を使用する次のいずれか
String[] arr = new String[RUNTIME_SIZE];
または実行時に、それのサイズを変更することができ、リストます:
List list = new ArrayList<String>();
私は知りませんが、あなたはあなたの変数のために動的に作成された名前を使用しようとしているならば、はい、間違いなく - 私はこのようにそれをやっています:
// rndRng() creates random numbers in specified range
// this would output dynamically created variable like "name89"
String myDynamicalyCreatedName = "name" + Utils.rndRng(0, 100);
final UberShader $myDynamicalyCreatedName = new UberShader();
あなたはここでのポイントのキーは基本的に「この記号の後に与えられた文字列から変数名を作成する」という記号「$」で見ることができ、そしてそれはそれは基本的だとして - 数年のために私のために魔法のように動作します今...それはあなたが何を望むかであり、それはあなたの問題を解決するビットを助けることを願っています。