Reputation: 127
Let's say I have a class named Person
and its constructor had variables like name
, age
, hairColor
and so on. If I had a function that receives a string that should match one of the class's variables, how could I check if that class actually had that variable and how could I go about modifying it? For example:
public class Person {
public String name;
public int age;
public String hairColor;
public Person() {
name = "Bryce";
age = 21;
hairColor = "brown";
}
public void changeHairColor(String variable, String color) {
if (/*this class contains the variable passed as an argument to this method*/) {
// Person[variable] = color
}
}
}
I'm a python dev, mostly, so the method changeHairColor
has some pseudo-python in it. I want to be able to edit the variable in a similar way you could edit variables inside of dictionaries with Python:
person = {
"name": "Bryce",
"age": 21,
"hairColor": "brown"
}
def changeHairColor(variable, color):
person[variable] = color
If that is at all possible.
Upvotes: 1
Views: 129
Reputation: 7956
I would not solve this with reflection. If your PlayerCharacter
has an enumerable set of attributes, I would model these as a Java enum
and store the attribute values within the PlayerCharacter
object in an EnumMap
:
import java.util.EnumMap;
public class PlayerCharacter {
public enum Attribute {
AGILITY,
DEXTERITY,
/* etc ...*/
VITALITY
}
private EnumMap<Attribute, Integer> attributes = new EnumMap<>(Attribute.class);
public PlayerCharacter() {
// initialize each attribute with a default value (0 in this example)
for (Attribute a : Attribute.values()) {
attributes.put(a, new Integer(0));
}
}
public int getValue(Attribute attribute) {
return attributes.get(attribute);
}
public void levelUp(Attribute attribute, int amount) {
attributes.put(attribute, attributes.get(attribute) + amount);
}
}
The biggest benefit of using an enum
instead of plain old String
(+reflection), is that this way you get compile-time type safety for the code that's using your PlayerCharacter
.
Upvotes: 1
Reputation: 10184
Using Reflection API, you can access the methods and properties on an object at run time. The other answer describes its usage. But I don't recommend reflections for your problem. How about the following:
public void changeHairColor(String variable, String color) {
if("name".equalsIgnoreCase(variable))
this.name = color;
else if("age".equalsIgnoreCase(variable))
this.age = Integer.parseInt(color);
else if("color".equalsIgnoreCase(variable))
this.color = color;
else
throw new Exception ("error - property not available");
}
}
Note, your existing method name 'changeHairColor' doesn't make sense in the context. It should be someething like 'changeProperty' because you are not just changing the 'color', you are changing any available property with this method.
Upvotes: 0
Reputation: 8229
The only way to do it in Java is to use Java Reflection API:
public class Test {
public String name;
public int age;
public String hairColor;
public void setProperty(String property, Object value) {
try {
Field declaredField = this.getClass().getDeclaredField(property);
switch (declaredField.getAnnotatedType().getType().getTypeName()) {
case "java.lang.String":
declaredField.set(this, value);
break;
// handle other types
}
} catch (NoSuchFieldException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}
}
public static void main(String[] args) {
Test test = new Test();
test.setProperty("name", "Bob");
System.out.println(test.name);
}
}
Upvotes: 3