我有一些变数:
float firstFloatSize = 0.0;
float secondFloatSize = 1.0;
float thirdFloatSize = 2.0;
float fourthFloatSize = 3.0;
我想从一个方法中更改这些变量,该方法将接收变量的名称和新值作为参数。像这样:
public void changeValue("firstFloatSize", 3.0);
如果我运行它,我会将变量“firstFloatSize”的值更改为3.0。
这会以某种方式成为可能吗?我知道我可以为浮点数创建一个包装类,并在该类中实现了这样的方法,但我只是好奇我是否能以另一种方式实现这一点。
答案 0 :(得分:1)
使用apache common setProperty
PropertyUtils
PropertyUtils.setProperty(this,"firstFloatSize", 3.0);
答案 1 :(得分:0)
你可以使用反射来做到这一点,但它会创建难以维护的代码。例如,更改变量名称将破坏反射代码:在运行时之前您不会注意到这一点。你也在规避封装(或许你没有注意到会员数据是公开的)。
我建议您使用set和get方法以正常方式执行此操作。
答案 2 :(得分:0)
如果这些字段的主要歧视点是" first"," second"等等,那么您可以使用数组来存储值,并设置方法它根据数组中的索引更改值:
float[] floatSizes = new float[]{ 0, 1, 2, 3 };
public void changeValueAtPosition(int index, float newValue){
floatSizes[index] = newValue;
}
这个例子当然缺少参数的一些常见保护(比如确保索引有效),并且可以通过使用标准类型(如枚举)而不是基元int来切换要更改的值来改进
更改" firstFloatSize"然后可以通过调用changeValueAtPosition(0, 3);
重申其他答案:如果有其他更简单的方法,请不要使用反射。基于反射的代码是任何项目规模的维护噩梦> 100 LOC。
答案 3 :(得分:0)
您基本上有两种选择:
编写自定义调度方法:
public void changeValue(String fieldName, float newValue)
{
// Java 6 style:
if("firstFloatSize".equals(fieldName)) {
targetClass.firstFloatSize = newValue;
} else if("secondFloatSize".equals(fieldName)) {
targetClass.secondFloatSize = newValue;
} else if // ... and so on
// or, alternatively, Java 7 style:
switch(fieldName)
{
case "firstFloatSize": targetClass.firstFloatSize = newValue; break;
case "secondFloatSize": targetClass.secondFloatSize = newValue; break;
// ... and so on
}
}
或使用反射:
public void changeValue(String fieldName, float newValue)
{
try
{
Field field = targetObject.getClass().getField(fieldName);
field.setFloat(targetObject, newValue);
}
catch( ... ) { ... }
}
我不知道你的花车是同一个班级还是另一个班级。如果它是同一个班级,显然你不需要targetObject
。否则,当然,您需要将targetObject
替换为对所需对象的引用。
请注意,两种方式都不是很好,因为其他评论已经说明了。两者都不是很易于维护,例如,如果你想在将来重命名其中一个浮点数,那么你必须手动检查所有出现的字符串,因为在这些情况下你的编译器无法确定是否正确。
另外(虽然这有点显而易见),如果你想要像这样访问多个类似的浮点数,你也可以创建一个数组并使用索引(可能由枚举备份)而不是字符串解决他们但这与原来的问题相差太远,所以我不会在这里详细说明......
答案 4 :(得分:0)
我建议使用第三方库。
但是如果你想使用Java原始API,下面是一个示例代码..
public class ReflectionSample {
private float value1 = 1.0f;
public float getValue1() {
return this.value1;
}
public void changeValue(String fieldName, float value) throws Exception {
Field field = this.getClass().getDeclaredField(fieldName);
boolean accessible = field.isAccessible();
field.setAccessible(true);
field.set(this, value);
field.setAccessible(accessible);
}
public static void main(String[] args) throws Exception {
ReflectionSample sample = new ReflectionSample();
sample.changeValue("value1", 3.0f);
System.out.println(sample.getValue1());
}
}
答案 5 :(得分:0)
作为一个良好的编码实践。
但请回到您的代码。
首先,如何定义浮点变量存在一个小问题。这些应该是
float firstFloatSize = 0.0f;
现在有几种方法可以实现这一目标。
最后,您的调用代码应该调用正确的set方法。希望它有所帮助。
public void changeValue(String property, float value) {
if(property.equals("firstFloatSize")) {
firstFloatSize = value;
} else if(property.equals("secondFloatSize")) {
secondFloatSize = value;
} else if(property.equals("thirdFloatSize")) {
thirdFloatSize = value;
} else {
fourthFloatSize = value;
}
}
答案 6 :(得分:0)
不确定你究竟需要以这种方式设置值,但这就是我没有反思的结果:
public class PropertySetter {
private float valOne;
private float valTwo;
private float valThree;
private float valFour;
public void setValue(FIELDS name, float value) {
switch (name) {
case valOne:
valOne = value;
break;
case valTwo:
valTwo = value;
break;
case valThree:
valThree = value;
break;
case valFour:
valFour = value;
break;
default:
throw new AssertionError(name.name());
}
}
public enum FIELDS {
valOne,
valTwo,
valThree,
valFour;
}
}
但是如果允许反射,那么我会这样做:
public class ReflectionSetter {
private float valOne;
private float valTwo;
private float valThree;
private float valFour;
public boolean setValue(String name, float value) {
Field[] fields = this.getClass().getDeclaredFields();
for (Field f : fields) {
if (f.getName().equals(name)) {
try {
f.setFloat(this, value);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionSetter.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
}
return false;
}
}
第一种方法有点难以维护,因为重构这个类将是一场噩梦。 第二种方式非常好,因为你只需要知道fieldname。