This might be the silliest question anybody ever asked, but just for curiosity, Can we assign values to Objects which are passed as arguments. For example
public class ForDemo3 {
int i = 0;
ArrayList cp = new ArrayList();
public ForDemo3() {
int j = 30;
cp.add(j);
cp.add(i);
i = 5;
j = 12;
System.out.println("i = " + i + " & j= " + j);
assignDvalues(i, j);
System.out
.println("After Restoring the values i = " + i + " & j= " + j);
}
public void assignDvalues(Object... obj) {
for (int n = 0; n <= obj.length - 1; n++) {
obj[n] = cp.get(n);
System.out.println("" + obj[n]);
}
}
public static void main(String[] args) {
new ForDemo3();
}
}
I'm trying to develop checkpoint based recovery in java. And cp
is a checkpoint object where values can be stored.
Output of Above is
i = 5 & j= 12
30
0
After Restoring the values i = 5 & j= 12
Edit
Apologies i am not a great user of stackoverflow. I'm working on a framework for parallel computing. And there will be a function savecheckpoint(List l)
which will be used to store list or array list to DB as a checkpoint, and another functionpublic object restoreCheckPoint(int i)
will restore the list. So far i'm able to save the checkpoint and then restore it back. But how can i assign back the values of the Objects or variables without effecting user's code? As given in the above example i want to restore the values using assignDvalues()
. Is there any way to make it possible?
This will be a real hack, so use it wisely. Following method uses reflection and has two limitations. Can not handle primitive types (because of autoboxing) and can not handle Strings initialised as constants (i.e. String s = "some string"
is not supported, but String s = new String("some string")
works fine). Also you should use new Integer(X)
instead of int x
not to mess the primitive types (similar story to Strings)
In belows example I replaced the int i
with Integer i
and the same for j
because as I said primitives are not supported.
The only thing which you would need to require by your users is to use "Integer" instead of "int", "Long" instead of "long" etc. and, what can be painful, avoid Strings defined as constants.
public class Demo2 {
Integer i = 0;
ArrayList cp = new ArrayList();
public Demo2() {
Integer j = 30;
String s = "def";
cp.add(j);
cp.add(i);
cp.add(s);
i = new Integer(5); // you need to use "i = new Integer(5)" instead of "i = 5" because you risk with messing the primitive int 5
j = new Integer(12); // here also you need to use new Integer(12)
s = new String("some string"); // NOTE: don't even try this with s ="some string" because this will lead to unexpected behaviour
//s = "some string" - if you pass string initialized this way you will mess up the string "some string" in jvm string pool
System.out.println("i = " + i + " & j= " + j + " & s= " + s);
assignDvalues(i, j, s);
System.out.println("After Restoring the values i = " + i + " & j= " + j + " & s= " + s);
}
public void assignDvalues(Object... obj) {
try {
for (int n = 0; n <= (obj.length - 1); n++) {
if (obj[n] instanceof Integer) {
Integer curInt = (Integer) obj[n];
Field field = curInt.getClass().getDeclaredField("value"); // Integer stores the real value in private field "value"
field.setAccessible(true);
field.set(curInt, cp.get(n));
System.out.println("" + obj[n]);
} else if (obj[n] instanceof String) {
String curS = (String) obj[n];
Field field = curS.getClass().getDeclaredField("value"); // String stores the text as char sequence in private field "value"
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); // need to reset final flag to override value of String
field.set(curS, ((String) cp.get(n)).toCharArray());
System.out.println("" + obj[n]);
} // else if (obj[n] insteanceOf SomeOtherType) { // you should provide implementation specific for each type/class you want to support with assignDvalues method
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public static void main(String[] args) throws Exception {
new Demo2();
}
}