是否可以在Java中动态设置对象属性(没有反射)?

Cli*_*ote 1 java

说我有以下课程:

class Foo
{
   public String bar;
   public String baz;
}
Run Code Online (Sandbox Code Playgroud)

我在另一个类中有以下代码:

Foo foo = new Foo();
String[] properties = {"bar", "baz"};
String[] values = {"barValue", "bazValue"};
Run Code Online (Sandbox Code Playgroud)

是否有可能迭代properties数组并使用它来设置值Foo?例如:

for (int i = 0; i < properties.length; i++)
{
  foo[ properties[i] ] = values[i];
}
Run Code Online (Sandbox Code Playgroud)

有可能像以上那样吗?

Ste*_*n C 5

有可能像以上那样吗?

没有.

使用您定义的属性,您唯一的选择是:

  • 编写或生成Java代码(或字节码)以引用字段a foo.barfoo.baz,或

  • 用反射.

如果需要动态属性,请使用Map对象; 例如HashMap<String, String>.


至于你的说明性例子,那将不会/不能工作,因为:

  • 常规对象字段不能像数组一样编入索引
  • 与C++,Python和其他语言不同,Java不支持任何核心语言结构的临时重载(除了方法).

Java不是支持这类事物的动态语言.你需要学会接受它能为你提供的东西......或者使用不同的语言.


你评论如此:

反思应该对表现不利.

是的,但它是相对的.反复访问或更新字段可能比使用普通Java代码访问/更新字段慢10到100倍.但是,如果您只是偶尔这样做,性能开销可能不相关.如果它确实是一个问题,那么您的选择包括手写或生成代码.例如:

public class Foo
{
   public String bar;
   public String baz;

   public void setNamedProperty(String name, String value) {
       switch (name) {
       case "bar": 
           bar = value;
           break;
       case "baz": 
           baz = value;
           break;
       default:
           throw new IllegalArgumentException("Unknown property name");
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

对于它的价值,该代码与在支持动态属性的语言中设置动态属性的时间效率相当.(我怀疑它会节省空间,因为动态属性通常使用本机编码哈希表实现.)