MBZ
MBZ

Reputation: 27592

access Class attribute my name

Can I access a Class attribute by its name?

for example:

class Test {
    Integer GoodVar;
    Integer BadVar;
    ...

    void Func(String name, Integer value) {
        // Set A Value based on its name
    }

    void Init() {
        Func("GoodVar", 2);
        Func("BadVar", 1);
    }
}

can somebody code Func function?

Upvotes: 2

Views: 128

Answers (4)

Priyank Doshi
Priyank Doshi

Reputation: 13151

Try this also:

package SO;

import java.lang.reflect.Field;

class Test {
    Integer GoodVar;
    Integer BadVar;

    void Func(String name, Integer value) throws IllegalArgumentException, IllegalAccessException {
    Field[] fields = this.getClass().getDeclaredFields();
    for (Field field : fields) {
        field.setAccessible(true);
        if (name.equals(field.getName())) {
        field.set(this, value);
        }
    }
    }
   // or a optimul way:
 void Func1(String name, Integer value) throws IllegalArgumentException, IllegalAccessException, SecurityException,
        NoSuchFieldException {
    Field field = this.getClass().getDeclaredField(name);
    field.setAccessible(true);
    field.set(this, value);
    }
    void Init() throws IllegalArgumentException, IllegalAccessException {
    Func("GoodVar", 2);
    Func("BadVar", 1);
    }

    @Override
    public String toString() {
    return "[GoodVar->" + GoodVar + ",BadVar-> " + BadVar + "]";
    }
}

With sample Main method :

package SO;

public class TestTest {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
    Test test = new Test();
    System.out.println(test);
    test.Func("GoodVar", 1);
    test.Func("BadVar", 2);
    System.out.println(test);
    }
}

It prints:

[GoodVar->null,BadVar-> null]
[GoodVar->1,BadVar-> 2]

Upvotes: 0

dan
dan

Reputation: 13272

You can use a switch statement, in JDK 7 the strings are allowed (see: http://docs.oracle.com/javase/7/docs/technotes/guides/language/strings-switch.html). Something like:

switch (name) {
     case "GoodVar":
         GoodVar = value;
         break;
     case "BadVar":
         BadVar = value;
         break;
     default:
         throw new IllegalArgumentException("Invalid name: " + name);
 }

Pre JDK 7 you can use if statements instead. Another approach it would be to use reflection (see: http://docs.oracle.com/javase/tutorial/reflect/index.html), but it's slow, like:

Field f = getClass().getField(name);
if (f!=null){
 f.setAccessible(true);
 f.setInt(this, value);
}else
  throw new IllegalArgumentException("Invalid name: " + name);  

Upvotes: 3

AlexR
AlexR

Reputation: 115328

What you are looking for is called reflection. You can do the following:

void Func(String name, Integer value) {
    Field f = getClass().getField(name);
    f.setAccessible(true); // needed because f is not public
    f.setInt(this, value)
}

But may I add some comments?

  1. fields, variables and methods by convention must start with small letter.
  2. Fields must be private. There are a couple of special cases when they can be protected or package protected. This is not your case.

Upvotes: 1

aymeric
aymeric

Reputation: 3895

Try this:

void Func(String name, Integer value) {
    // Set A Value based on its name
    Field f = getClass().getDeclaredField(name);
    f.setAccessible(true);
    f.set(this, value);
}

Upvotes: 0

Related Questions