是否可以在 Java 中动态生成变量的名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1192534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there away to generate Variables' names dynamically in Java?
提问by M. A. Kishawy
Let's say that I need to generate variables to hold some input from the user (I don't know how many they are). Without using Array
, ArrayList
(and other kind of lists and maps) can my code generate (lets say) String
variables X times with names like (String var001
, String var002
, String var003
, etc)? If yes, please provide sample code.
假设我需要生成变量来保存来自用户的一些输入(我不知道它们有多少)。如果不使用Array
, ArrayList
(以及其他类型的列表和映射),我的代码是否可以生成(假设)String
变量 X 次,名称类似于 ( String var001
, String var002
, String var003
, 等)?如果是,请提供示例代码。
采纳答案by gmhk
Following is the way that i have implemented and helped me to fix my solution easily without much hurdles.
以下是我实施并帮助我轻松修复解决方案而没有太多障碍的方式。
// Creating the array List
// 创建数组列表
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
Iterating the loop and adding the objects into the arraylist with the index.
迭代循环并将对象添加到带有索引的数组列表中。
//Retrieving the object at run time with the help of the index
//在运行时借助索引检索对象
String a = accountList.get(i));
回答by Markus Lausberg
You mean you want to generate variables named
你的意思是你想生成名为的变量
var0, var1, var2 and use them in your code.
var0、var1、var2 并在您的代码中使用它们。
What is the difference when you use var[0], var[1], var[2], .....
使用 var[0], var[1], var[2], ..... 有什么区别
BUT
但
You can generate a Java class dynamically at runtime which implements an Interface you are using in your normal code. Then you compile this class using a compiler (For example Janino) and then load the class at runtime. Than you have created a class dynamically.
您可以在运行时动态生成 Java 类,该类实现您在普通代码中使用的接口。然后使用编译器(例如 Janino)编译此类,然后在运行时加载该类。比您动态创建了一个类。
But i wonder, whether this is necessary for your usecase.
但我想知道,这对于您的用例是否必要。
EDIT
编辑
I dont now for which usecase you are using this parameters but dynamic arguments you can use in Java like this example from here
我现在不知道你在哪个用例中使用这个参数,但是你可以在 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
回答by Yuval Adam
This is not possible, but this is a perfect candidate for using one of the java collections.
这是不可能的,但这是使用其中一个 java 集合的完美候选者。
Either use a dynamically allocated array:
要么使用动态分配的数组:
String[] arr = new String[RUNTIME_SIZE];
Or a list which can change it's size during runtime:
或者可以在运行时更改其大小的列表:
List list = new ArrayList<String>();
回答by Stroboskop
Naming variables like that looks very 1980-ish. Meaning pre object oriented programming. So if you ever build software for a living - DON'T DO THIS.
像这样的命名变量看起来非常 1980 年风格。意思是面向对象编程。因此,如果您曾经为谋生而构建软件 - 不要这样做。
But since it seems to be homework...
但因为它似乎是家庭作业......
When we're talking about a named variable in Java, we mean something that's compiled. Unlike in some scripting languages there is no easy way to do this in Java.
当我们谈论 Java 中的命名变量时,我们指的是经过编译的东西。与某些脚本语言不同,在 Java 中没有简单的方法可以做到这一点。
So either you use a runtime compiled class like Markus Lausberg suggested.
Or you cheat and use the Java Scripting APIand make use of the scripting languages. That way you can create code (in a String) at runtime.
因此,要么使用 Markus Lausberg 建议的运行时编译类。
或者您欺骗并使用Java Scripting API并使用脚本语言。这样您就可以在运行时创建代码(在字符串中)。
回答by user85421
I think you can generate a Java class at runtime or maybe use some script engine like Beanshellto generate the variables, you can even build the class by its bytecode. But I can't see how you will use that variables in your code, you must also create the code to work with that variables, or use reflection for that...
我认为你可以在运行时生成一个 Java 类,或者使用一些像Beanshell这样的脚本引擎来生成变量,你甚至可以通过它的字节码来构建这个类。但是我看不到您将如何在代码中使用该变量,您还必须创建代码以使用该变量,或者为此使用反射...
A naive solution:
create a class with all variables from var000 to var999 with a getter for each... but that's not really dynamically!
一个天真的解决方案:
创建一个包含从 var000 到 var999 的所有变量的类,每个变量都有一个 getter……但这并不是真正动态的!
回答by Denis Tulskiy
Without using Array, ArrayList (and other kind of lists and maps)
不使用 Array、ArrayList(以及其他类型的列表和映射)
Create files with these names. Hope that will work for your professor.
创建具有这些名称的文件。希望这对你的教授有用。
Or use the Java Scripting API mentioned before:
或者使用之前提到的 Java Scripting 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
编辑
Seems like internally this will use Maps :) Same with Properties file, Preferences API, or DOM Trees (they are using Vectors). So if your professor is so picky, use files.
似乎在内部这将使用 Maps :) 与 Properties 文件、Preferences API 或 DOM 树(它们使用 Vectors)相同。因此,如果您的教授如此挑剔,请使用文件。
回答by Beska
I haven't seen this answered yet, so I'll go for it. Write a program that just writes out Java source code. Most of it could be a template, and you would just have a loop that would write as many "string UserString003" type variables as you want.
我还没有看到这个答案,所以我会去做。编写一个只写出 Java 源代码的程序。其中大部分可能是一个模板,您只需一个循环,可以根据需要编写尽可能多的“字符串 UserString003”类型变量。
Yes, this is horrible. But, as you said, it's a conceptual challenge problem for homework, so as long as no one mistakes this for "good" code, it might solve the issue.
是的,这太可怕了。但是,正如您所说,这是家庭作业的概念挑战问题,因此只要没有人将其误认为“好”代码,它就可能解决问题。
回答by Esko Luontola
If you reallywant to do something like that, you can do it through bytecode generation using ASMor some other library.
如果你真的想做这样的事情,你可以通过使用ASM或其他库的字节码生成来完成。
Here is code that will generate a class named "foo.bar.ClassWithFields" that contains fields "var0" to "var99". Of course there is no way other than reflection to access those fields, because they don't exist at compile time and Java is a statically typed language.
下面的代码将生成一个名为“foo.bar.ClassWithFields”的类,该类包含字段“var0”到“var99”。当然,除了反射之外没有其他方法可以访问这些字段,因为它们在编译时不存在,而且 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);
}
}
}
回答by Edison Gustavo Muenz
It looks like your professor is PHP-biased on the feature (Variable variables), so he was thinking if that was possible in java.
看起来您的教授对功能(变量变量)有 PHP 偏见,所以他在想这在 Java 中是否可行。
I personally don't think that this is possible, not in the way you are proposing. What can be done is the generation of classes at runtime, using tools like Javassistto make a more powerful reflection mechanism. So you can create a class that has the variables you want (string1, string2, etc.) at runtime.
我个人认为这是不可能的,不是按照你提议的方式。可以做的就是在运行时生成类,使用Javassist之类的工具来制作更强大的反射机制。因此,您可以在运行时创建一个具有所需变量(string1、string2 等)的类。
However, don't forget that Variable variablesis a really bad technique, which leads to bad code. It might be useful on very few cases, but I really don't recommend it.
但是,不要忘记Variable 变量是一种非常糟糕的技术,它会导致糟糕的代码。它可能在极少数情况下有用,但我真的不推荐它。
回答by theoneiam
I do not know if I understood you correctly but if you are trying to use dynamically created names for your variables then yes, definitely - I am doing it like this:
我不知道我是否理解正确,但是如果您尝试为变量使用动态创建的名称,那么是的,绝对 - 我是这样做的:
// 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();
As you can see the point key here is the sign "$" that basically says "create variable name from the String that is given after this sign", and that's basically it - works like a charm for me for a few years now...hope it is what you wanted and that it helps a bit solving your problem.
正如你所看到的,这里的关键是符号“$”,它基本上是说“从这个符号之后给出的字符串创建变量名”,基本上就是这样 - 几年来对我来说就像一个魅力...... .希望这是你想要的,它有助于解决你的问题。