0

I'm playing with Object-Oriented programming in Java language and I got some idea but I'm now sure is it possible to implement.

class Class()
{
     int a,b,c;
     ...

     public void method(int x){...}
     ...

}

And now is it possible to pass name of variable which is located in that class like this:

obj.method(a);

I know to do this on two ways:
1. To pass obj.a
2. To pass some kind of id and to resolve that id inmethod()

But I'm curious to know is it possible to pass only a name of variable?

Better explanation: My question is it possible to pass string which consist name of variable, and than resolve this in method and get reference to it?

encrypt
  • 77
  • 1
  • 11
  • 2
    you want to call a method on class and pass in members that belong to that class? Why? – austin wernli Jul 07 '15 at 14:29
  • 3
    Could you please try and describe what you want to do a little clearer? – Gemtastic Jul 07 '15 at 14:31
  • why not? Probably I want to choose same settings in the class. – encrypt Jul 07 '15 at 14:32
  • @encrypt you can access the field in the class by just referring it in `method()`. No need to accept as a parameter. – Dhanush Gopinath Jul 07 '15 at 14:32
  • If you know the name of the variable, why not just reference the variable directly instead of by its pre-compiled name? Why even pass a value to a method on the object which already has that value? It's not really clear what you're trying to do, and I suspect the problem is a lack of understanding of OO. – David Jul 07 '15 at 14:33
  • @Gemtastic OK, for example I have class Car and in that class three variable, for example red,blue,white which consist color hex code. And now I want to call car.color(red) and make it red. – encrypt Jul 07 '15 at 14:34
  • No, what you want is not possible in Java; there is no such thing as a "field literal" like there is a "class literal" (`MyClass.class`). You can pass an instance of `java.lang.reflect.Field` to do something like that, but that is not nearly close to "passing the name of a variable". – Erwin Bolwidt Jul 07 '15 at 14:34
  • @ErwinBolwidt how about a string containing the variable name? – bratkartoffel Jul 07 '15 at 14:39
  • @encrypt In the car example, you should treat the color as a separate type (class) and (when we use the built-in `java.awt.Color` class for example) then we can do `car.setColor(Color.red)`. – Chronio Jul 07 '15 at 14:39
  • @bratkartoffel For example to pass variable name in that way, is it possible? – encrypt Jul 07 '15 at 14:41
  • @Chronio yes ok, but this is not my question. My question is: Is it possible to do without accessing another class – encrypt Jul 07 '15 at 14:42
  • It's possible, but not recommeded and OO-like at all. As such I'd recommed looking for other solutions. If you still insist, however, I could add an answer showing you how to do this with Java's Reflection API. – Chronio Jul 07 '15 at 14:44
  • @encrypt I describe such a way briefly in my answer below – bratkartoffel Jul 07 '15 at 14:45
  • 1
    @bratkartoffel What are you going to do with a string containing a variable name? Short of using it to look up a `java.lang.reflect.Field` instance I mean. – Erwin Bolwidt Jul 07 '15 at 14:47
  • @ErwinBolwidt Just re-read your comment. You're right, I mixed something up. – bratkartoffel Jul 07 '15 at 14:54
  • You definitely have a misunderstanding of OO concepts – austin wernli Jul 07 '15 at 14:59

4 Answers4

1

You appear to want to pass the name of a parameter into a method and then do something with that parameter. You seem to be intent on not providing any context of your problem, which leads me to believe you are merely interested in the possibility, and are not looking to use this in actual application code. As such, I will show you for the sake of reference:

public void method(String parameterName) {
    try {
        // We can get the current field value:
        int value = (int) getClass().getField(parameterName).get(this);

        // And update it (for example, set it to 23)
        getClass().getField(parameterName).set(this, 23);
    catch (NoSuchFieldException | IllegalAccessException ex) {
        // Field does not exist or is not public.
    }
}

It can be used as follows (this sets the value of field a to 23 if it exists).

MyClass instance = new MyClass();
instance.method("a");

Note that this requires the field to be public. It is possible to this with non-public fields as well but that is an even worse idea, since it bypasses the entire access control mechanism of Java. There are better solutions which involve using a Map object to implement a similar kind of structure. These are definitely better than using this.

Last remark (I cannot stress this enough): Do not use Reflection calls in actual code! It is always possible to do everything you need to without it (For example, use a Map<String, Integer> instead of individual fields).

Chronio
  • 757
  • 3
  • 8
0

It seems like you want to do something to the field of your class: Class? There is a specific set of operations for this in OOP called "mutators". There is also "accessors" to access fields of a class.

Note these are not required of course but it is good practice. Encapsulation is an important feature of object oriented programming, and having direct access to the inner parts of a class can lead to confusion in regards to what a class actually does.

class Class()
{
     int a,b,c;
     ...

     //mutator for a
     public void setA(int newValue)
     {
          //...do something do a?
          a = newValue;
     }

     //accessor for a
     public int getA()
     {
          return a;
     }

}

Now that OOP is covered, you can do what you are asking through reflection, but there are few situations that I think actually warrant the use of reflection and this is not one of them.

James Wierzba
  • 16,176
  • 14
  • 79
  • 120
0

I think the poster wants a "multi-purpose-super-dynmic-method", working only on specific attributes of the class definied by the caller.

Your first way is not possible, as your attributes are effectivly protected from direct access by an extern class. You could declare your attributes as public, but this would be a very bad idea. Another option would be to create getters and setters for your attributes and use them instead of directly referencing your attributes. This would be a clean solution and I think the best "OOP-way" to do so.

Your second way is possible, but not so easy to implement. This would need Reflection to access the attributes and can introduce some nasty bugs and unexpected behaviour at runtime. That would also defeat the purpose of using setters and getters to provide access control and validation for your attributes.

Conclusion: Stick to getters and setters. They're very handy and everyone uses them.

bratkartoffel
  • 1,127
  • 1
  • 13
  • 37
  • This code above was only rough presentation of my idea. Yes of course i must define variables as public if i want to do this. In second way I think to pass integer and in method if integer is 1 than use this variable and so on. – encrypt Jul 07 '15 at 14:46
  • Can I for example pass name of variable like a string and in method resolve this and get reference to variable. – encrypt Jul 07 '15 at 14:46
  • Sorry, but I think you're asking the wrong questions. It seems you're about to learn Java and OOP in general, but these questions are more for "advanced" programmers. I'd suggest you stick with getters and setters, then learn about some design patterns and "ways-of-doing / conventions" in the java world. If your application is well designed and planned, reflection is not necessary to achieve your goals. Reflection in general should only be the last way out if you have definitly no other way to do something in a proper way. – bratkartoffel Jul 07 '15 at 14:52
0

If you only want to pass the colour into the object as a string, you could write a switch case for the provided content, like this (using your car example in the comments):

public class Car {
    private String red = "#ff0000";
    private String white = "#ffffff";
    private String black = "#000000";

    public String colour(String colour) {
        String input = colour.toLowerCase();
        switch(input) {
            case "red":
                return red;
                break;
            case "white":
                return white;
                break;
            case "black":
                return black;
                break;
            default:
                System.out.println("The car doesn't come in that colour :(");
                return null;
                break;
        }
    }
}

* Note that the break cases after the returns are unnecessary, but I put them there just to be safe.

However, this does sound like a design flaw in the code. If you just want to access the values in the object I recommend you use getters and setters.

Community
  • 1
  • 1
Gemtastic
  • 6,253
  • 6
  • 34
  • 53