I am creating a lot of objects called: Obj1, Obj2.... ObjX
Object Obj1 = new Object();
Object Obj2 = new Object();
Object ObjX = new Object();
Now I am having a function where I want to get access to one of this objects.
public void useObject(int objectNumber) {
String objectName = "Obj" + objectNumber;
objectName.doAnythingWithThisObject();
}
Is something like that possible in C# or Java? I don't want to use something like:
switch(objectNumber) {
case 1:
Obj1.doThis();
break;
case 2:
Obj2.doThis();
break;
If I would use switch/if-else then I have to repeat a lot of code which make this thing less readable, because I have to call the same function with different objects.
4 Answers 4
The actual answer is: you shouldn't, generally speaking, access your variables, using strings at runtime. Cases where this is actually appropriate are few and far between and your example, simplified though it may be for illustration purposes, is not a good match for it.
Instead, why don't you simply use a collection or an array to store your objects? @T.R.Rohith gives an example in their answer.
Still, the direct answer to your question, as it applies to Java, is given below. While the code would be different for C#, the language feature, which can be used for this purpose, namely, reflection, is available in C# as well.
If Obj1
, Obj2
etc. are declared as static or instance fields in a class, you can get their values by their names using reflection (see relevant docs for Java). If they are local to a method, there is no simple way to do so (see these questions: for Java, for C#).
Static fields
class Something {
static Object obj1 = new Object();
static Object obj2 = new Object();
// etc.
}
(I've taken the liberty of starting field names with lowercase letters, as it the accepted practice in Java.)
In this case you can get the value of the variable by its name using the following code (you need to import java.lang.reflect.Field
):
// Get field, named obj1, from class Something.
Field f = Something.class.getDeclaredField("obj1");
// This line allows you access the value of an inaccessible (non-public) field.
f.setAccessible(true);
// Assigning the value of the field, named obj1, to obj.
// You may want to cast to a more concrete type, if you know exactly what is stored in obj1.
// The parameter for get() is ignored for static fields, so simply pass null.
Object obj = f.get(null);
// Now you can do whatever you want with obj,
// which refers to the same object as static field obj1 of Something.
System.out.println(obj);
Instance fields
class Something {
Object obj1 = new Object();
Object obj2 = new Object();
// etc.
}
You can do it in almost exactly the same way for instance fields, you just need an instance of the class to pass to f.get()
. So, for the sake of example, let's assume we have an instance of class Something
, called sth
.
// Let's say this is an instance of our class
Something sth = new Something();
// ...
// Get field, named obj1, from class Something.
Field f = Something.class.getDeclaredField("obj1");
// This line allows you access the value of an inaccessible (non-public) field.
f.setAccessible(true);
// Assigning the value of the field, named obj1, to obj.
// You may want to cast to a more concrete type, if you know exactly what is stored in obj1.
// The parameter for get() is the instance of Something,
// for which you want to retrieve the value of an instance field, named obj1.
Object obj = f.get(sth);
// Now you can do whatever you want with obj,
// which refers to the same object as instance field obj1 of sth.
System.out.println(obj);
Local variables
You are probably out of luck in this case. Again, see the following links: Java, C#.
This sounds like a classic Strategy pattern problem Strategy Design Pattern
Here's the code:
//Declare this in the class so that it can be called by any method
static Object[] array = new Object[4];
public static void main()
{
//Use this to initialize it
Object[] array = new Object[4];
for(int i=0;i<4;i++)
{
array[i] = new Object();
}
//You can now easily call it
useObject(0);
useObject(1);
useObject(2);
useObject(3);
}
//Your numbers may be off by 1 because we are using an array but that is easily adjusted
public static void useObject(int objectNumber)
{
array[objectNumber].doAnythingWithThisObject();
}
The answer is... don't. Use an array instead. This is exactly what they're for.
ObjectType[] objectArray = new ObjectType[10]; // Or as many as required.
for (int i = 0; i < objectArray.length; i++) {
objectArray[i] = new ObjectType(); // Or whatever constructor you need.
}
// Then access an individual object like this...
ObjectType obj = objectArray[4];
// Or...
objectArray[5].someMethod();
Explore related questions
See similar questions with these tags.
Obj1
,Obj2
etc. declared? Are they static, instance or local variables?Object
class store aint ObjectNumer;
which is only set in the constructor by using astatic int objectCount;
field which gets incremented on each construction of such an object. You can then save a reference of allObject
objects somewhere sothat you can later pull out the right object according to theobjectNumber
. (i.e., singleton method)