0

I want to read value of a string array constant dynamically.

Constant class has string array of car. NeedValueOf will dynamically append with constant name i.e Constants.needValueOf

Tell me the way to get value dynamic and after getting object i want value from that object. I want to get all the string array values in my method so that i can iterate and access the string car names

Class Constants{
Private final static String[] car ={"Honda","Toyota", "Volkswagen"};
}
Class Main{
Public static void main(){
String needValueOf ="car";
Constants.class.getDeclaredFields(needValueOf).get(null);
}
}


It is providing : [Ljava.lang.String;@47483]
Amol
  • 7
  • 4
  • Please show your actual code, copied and pasted, in questions instead of retyping it. – tgdavies Dec 15 '21 at 20:45
  • Class.forName("Constants").getDeclaredField("car").get(null); – Amir Afghani Dec 15 '21 at 20:47
  • @AmirAfghani that isn't a static field – tgdavies Dec 15 '21 at 20:50
  • It probably should be. – Amir Afghani Dec 15 '21 at 20:52
  • @tgdavies I've formatted the code. – Amol Dec 15 '21 at 20:55
  • It is a static field..i was doing in same way – Amol Dec 15 '21 at 20:56
  • But not able to retrieve the values from object. I need help to retrieve value from object which i am getting from 7th line. – Amol Dec 15 '21 at 20:57
  • What is your goal? Why are you using reflection? "I want to read value of a string array constant dynamically." - what does this even mean? – hfontanez Dec 15 '21 at 20:59
  • I want to get the string array values from dynamic append of variable from constants class. – Amol Dec 15 '21 at 21:02
  • Your code is full of syntax errors. And you still didn't answer my question as to why are using reflection. Is your goal to learn about how reflection works? – hfontanez Dec 15 '21 at 21:04
  • I dont find any other way but reflection. I will appreciate if you solve this with some simple logic my goal is to get the string array values in main method but dynamically append the variable at place of constant. – Amol Dec 15 '21 at 21:05
  • I typed from mobile phone that's why it has syntactical errors..sorry for that – Amol Dec 15 '21 at 21:06
  • You can provide a `print()` method in the `Constants` class, you can provide an ordinary getter method to return a copy of the array. There are ways other than reflection to accomplish the same. That's why I am asking "What is your goal?" What are you trying to learn. – hfontanez Dec 15 '21 at 21:07
  • I have 10 fields. If i write getters it will get lengthy. I want to dynamically append my variable at place of constant and retrieving the values. – Amol Dec 15 '21 at 21:08
  • That alone is not a good reason to use reflection. Reflection comes with a lot of drawbacks, one of which is performance. 99.99% of the time, reflection is the worst choice you can make. The rest of the time is just a bad choice to make. IN FACT, why make the array private if you are just going to use reflection to have access to it? Just make the array public and be done with it. Then, it is a matter of calling it by name `Constants.car`. – hfontanez Dec 15 '21 at 21:13
  • Okay. Could you please provide me a logic? I hope you understand the problem. Sir i dont want to call it by name. That car will replace with needValueOf variable and i need value from that. – Amol Dec 15 '21 at 21:14
  • Actually that needValueOf variable is dynamic. I have 10 more fields. Car bike books etc so it will be like this Constants.needValueOf and needValueOf can be replaced with car,bike ,books etc. So with this i can save lines of code. – Amol Dec 15 '21 at 21:18
  • Another few observations: 1) `getDeclaredField()` will not work because the field if private. You have to make the field non-private instead. 2) You have to use fully qualified name (package plus class name) when using `Class.forName()`. There is a more complex way to obtain private fields. But again, it is not necessary. – hfontanez Dec 15 '21 at 21:29
  • @Amol I posted an answer with an update that should be exactly what you need without using reflection. – hfontanez Dec 15 '21 at 21:41

2 Answers2

0

Since the array is a constant, simply make the array public and access it by name.

public class Constants{
    public final static String[] car ={"Honda","Toyota", "Volkswagen"};
}

public class Main{
    public static void main(String[] args){
        String[] arr = Constants.car; // access it by name
    }
}

Don't need to use reflection. 99.99% of the time, reflection is the worst choice you can make. The rest of the time is just a bad choice.

If the array wasn't constant, you can provide a getter method and create a defensive copy of the array. But that is out of scope based on your question.

UPDATE:

If "dynamic" is the main emphasis because there are many array constants and you want to access them by passing a String, all you need is place them in a map.

public class Constants{
    private final static String[] cars ={"Honda","Toyota", "Volkswagen"};
    private final static String[] boats = {...};
    public static Map<String, String[]> myConstants = new HashMap<>();

    public Constants () {
        myConstants.put("cars", cars);
        myConstants.put("boats", boats);
    }
}

public class Main{
    public static void main(String[] args){
        String[] carsArr = myConstants.get("cars");
        String[] boatsArr = myConstants.get("boats");
    }
}

The map should not be public static. It should not even be modifiable. All access should be controlled via methods. That way, you can control what is passed outside the class (i.e. a copy of the map).

hfontanez
  • 5,774
  • 2
  • 25
  • 37
0

[Ljava.lang.String;@47483 is simply toString on a String[].

You are retrieving the value correctly.

To use it, do:

public class App {

    private static final String[] car = {"Honda", "Toyota", "Volkswagen"};

    public static void main(String... args) throws NoSuchFieldException, IllegalAccessException {

        String needValueOf = "car";
        String[] xs = (String[]) App.class.getDeclaredField(needValueOf).get(null);
        System.out.println(xs);
        for (String x : xs) {
            System.out.println(x);
        }
    }
}

which prints:

[Ljava.lang.String;@41629346
Honda
Toyota
Volkswagen
tgdavies
  • 10,307
  • 4
  • 35
  • 40