1

I have 3 ints named A, B, and C. These are to be multiplied with the number 52. I have a string that contains the name of which int I want to mulitply (in example below my string type == A;.

I want to know if there is anyway to make the name of the String change into the name of the object/int that I wish to use.

What I have right now:

public class MultiplySomeNumbers{
    int A = 100;
    int B = 200;
    int C = 300;
    String type = "A";

    final int multiplied = 52;

    public int multiply(String type){
        return multiplied* ____ //What goes here?
    }

} 

I DON'T want to do anything like this:

public int multiply(String type){
    if(type.equalsIgnoreCase("A"){
        return multiplied*A;
    }else if(type.equalsIgnoreCase("B"){
        ...

Any help would be greatly appreciated!

XQEWR
  • 638
  • 3
  • 11
  • 24

4 Answers4

3

No, that is not possible (maybe with Reflection, but it's still a no-go). Every single situation where you think you might need this does not need it.

There are several issues, but here are a few:

  • No intellisense for those generated variables
  • Very unclear code
  • Ambiguous naming (what if you create a new variable that happens to have the same name as a generated one?)
  • etc etc etc

You will have to go with your second option.

We might be able to provide a different solution, but the question is rather unclear as it is right now. Perhaps you could expand a little so we can help you better.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
  • As far as different solutions, from the little we have, it sounds like a good use case for enums. – yshavit Nov 21 '13 at 00:22
  • Looks like it indeed. Refer to Jonathan's answer for an example implementation of an `enum`. – Jeroen Vannevel Nov 21 '13 at 00:26
  • @yshavit: I would not use an enum for this. Enums are intended to have the sense of constants (all of which are known at compile time). Constants are antithetical to the sense of variables. If the fields had all been declared `static` and `final`, then I'd agree with you absolutely that an enum was the way to go. Since they're not, I'd favor a solution using the Collections API. – scottb Nov 21 '13 at 01:13
  • @scottb: they *are* treated as constants. The enum and its value are constants but that doesn't mean you can't use those constants in equations. – Jeroen Vannevel Nov 21 '13 at 01:15
  • @JeroenVannevel: Absolutely. If those fields are intended to represent constants (I'm looking at the OP's code), then they really ought to be declared `static` and `final`. Since they are not, I can only assume that they are intended to serve as variables set to initial values. In such a case, an enum can still be made to work (if the enum fields are single-element arrays), but it is hardly optimal. For variable quantities, a Map is much better suited to this problem than an enum. – scottb Nov 21 '13 at 01:18
  • @scottb This isn't meant as a dig to the OP, but if they're at a point where they don't know how to do this sort of string-to-int mapping, they may well not know about `static final`. I don't know if it's safe to assume they're intended to be mutable; my _guess_ would be that they're not, just on a gut. If they are, I fully agree with you that an enum would be inappropriate. – yshavit Nov 21 '13 at 02:25
2

Although there may be a way to do this with reflection, it's probably a really bad idea. If you really can't just pass in the value, but want to specify a limited set of constants by which you can multiply, I'd recommend creating an enumerated type.

Taking your same example, but using an enum instead of trying to look up constants by name, would look something like this:

public class MultiplySomeNumbers{
  public enum Type {
    A(100),
    B(200),
    C(300);

    private final int value;

    private Type(int value) {
      this.value = value;
    }

    public final int getValue() {
      return value;
    }
  }

  Type type = Type.A;

  final int multiplied = 52;

  public int multiply(Type type){
    return multiplied * type.getValue();
  }
} 
Jon Newmuis
  • 25,722
  • 2
  • 45
  • 57
1

While there is nothing wrong with using an enum for this solution, it may not be the most flexible solution. Enums are, by design, effectively immutable ... they are intended to have the sense of constants. If you wish to change the value of a variable by multiplying its value by 52, then this is not possible with enums.

What I think you really should do is use a HashMap. A Map is a key / value pair.

  • The key is the "variable's name"; a String quantity
  • The value is the "variable's current value"; an Integer quantity (not int!)

Your Map can be declared like this:

Map<String, Integer> myVariables = new HashMap<String, Integer>();

then to load your variables into the map, you simply call the Map's put() method:

myVariables.put("A", Integer.valueOf(100));
myVariables.put("B", Integer.valueOf(200));
myVariables.put("C", Integer.valueOf(300));

Retrieving the value of a variable is as simple as using the get() method with your variable name as the key:

int val = myVariables.get("A").intValue();

Notice that I have chosen to box and unbox the primitive int values myself rather than rely on autoboxing. This is just a personal choice. It does trade off conciseness, but I'd rather see what's actually happening.

In my opinion, using reflection to determine a class field to access dynamically at run time is wholly unsatisfactory and should be avoided ... most especially since using the Java Collections API enables a statically typed, type safe solution that can be checked at compile time.

scottb
  • 9,908
  • 3
  • 40
  • 56
0

You can't check for a variable's name. For more information look here, there are some good answers: Java Reflection: How to get the name of a variable?

But maybe a HashMap can help you, where you store "A", "B", "C" as keys and the respective numbers as value.

edit: Okay, maybe with something like this http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html it could be possible.

Community
  • 1
  • 1
Sebastian Höffner
  • 1,864
  • 2
  • 26
  • 37