Created
October 29, 2015 03:18
-
-
Save chandu-io/21dd4a066b9081a10645 to your computer and use it in GitHub Desktop.
java :: getReference
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This method will return the reference to the internal private/protected/public/default fields of the given object. | |
* This method can go as deeper as needed; with the passed `fields` parameter. | |
* The parameter `fields` array follows order from outer `object variable name` to `inner variable name` | |
* See below example: | |
* - getReference(obj, "var", "var", "var:list:0", "var:array:0", ">>var", "var:map:custom_key", "var:set:1") | |
*/ | |
public static Object getReference(final Object obj, final String... fields) throws Exception { | |
if (fields.length < 1 || fields[0] == null) { | |
return obj; | |
} | |
String fieldName = fields[0]; | |
Class<?> cls = obj.getClass(); | |
while (fieldName.startsWith(">")) { | |
cls = cls.getSuperclass(); | |
fieldName = fieldName.substring(1); | |
} | |
if ("".equals(fieldName)) { | |
return obj; | |
} | |
final String fieldParts[] = fieldName.split(":"); | |
final Field field = cls.getDeclaredField(fieldParts[0]); | |
field.setAccessible(true); | |
Object child = field.get(obj); | |
field.setAccessible(false); | |
final String[] childFields = Arrays.copyOfRange(fields, 1, fields.length); | |
if (fieldParts.length != 1) { | |
int index = -1; | |
try { index = Integer.parseInt(fieldParts[2]); } catch (final Exception e) {} | |
if (fieldParts[1].equals("array") && index != -1) { | |
if (child instanceof Object[]) { | |
Object[] childArray = (Object[]) child; | |
child = childArray[index]; | |
} else if (child instanceof int[]) { | |
int[] childArray = (int[]) child; | |
child = childArray[index]; | |
} else if (child instanceof short[]) { | |
short[] childArray = (short[]) child; | |
child = childArray[index]; | |
} else if (child instanceof byte[]) { | |
byte[] childArray = (byte[]) child; | |
child = childArray[index]; | |
} else if (child instanceof long[]) { | |
long[] childArray = (long[]) child; | |
child = childArray[index]; | |
} else if (child instanceof double[]) { | |
double[] childArray = (double[]) child; | |
child = childArray[index]; | |
} else if (child instanceof float[]) { | |
float[] childArray = (float[]) child; | |
child = childArray[index]; | |
} else if (child instanceof boolean[]) { | |
boolean[] childArray = (boolean[]) child; | |
child = childArray[index]; | |
} | |
} else if (fieldParts[1].equals("list") && index != -1) { | |
List<?> childList = (List) child; | |
child = childList.get(index); | |
} else if (fieldParts[1].equals("set") && index != -1) { | |
List<?> childList = new ArrayList<Object>((Set) child); | |
child = childList.get(index); | |
} else if (fieldParts[1].equals("map") && index == -1) { | |
Map<String, ?> childMap = (Map<String, ?>) child; | |
child = childMap.get(fieldParts[2]); | |
} | |
} | |
return getReference(child, childFields); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TestIt { | |
public static void main(String[] args) throws Exception { | |
System.out.println(ReflectionReference.getReference(new A(), "var1")); | |
System.out.println(ReflectionReference.getReference(new A(), "var")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var", "var:list:0")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var", "var:list:0", "var")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var", "var:list:0", "var", "var:array:2")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var", "var:list:0", "var", "var1:set:1")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var", "var1:map:key2")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", "var")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", ">svar")); | |
System.out.println(ReflectionReference.getReference(new A(), "var", ">>ssvar")); | |
} | |
} | |
class A { | |
private final B var; | |
private final double var1; | |
public A() { | |
var = new B(); | |
var1 = 99.99d; | |
} | |
@Override | |
public String toString() { | |
return String.format("A={%s, s}", var, var1); | |
} | |
} | |
class B extends F { | |
private final C var; | |
public B() { | |
var = new C(); | |
} | |
@Override | |
public String toString() { | |
return String.format("B={%s}", var); | |
} | |
} | |
class C { | |
private final List<D> var; | |
private final Map<String, String> var1 = new HashMap<String, String>() {{ | |
put("key1", "Chandu's secret");put("key2", "Something else"); | |
}}; | |
public C() { | |
var = Arrays.asList(new D(), new D()); | |
} | |
@Override | |
public String toString() { | |
return String.format("C={%s}", var); | |
} | |
} | |
class D { | |
private final E var; | |
public D() { | |
var = new E(); | |
} | |
@Override | |
public String toString() { | |
return String.format("D={%s}", var); | |
} | |
} | |
class E { | |
private final boolean[] var; | |
private final Set<Integer> var1 = new LinkedHashSet<Integer>() {{ | |
add(123);add(546); | |
}}; | |
public E() { | |
var = new boolean[]{true, false, true}; | |
} | |
@Override | |
public String toString() { | |
return String.format("E={%s}", Arrays.toString(var)); | |
} | |
} | |
class F extends G { | |
private final String svar; | |
public F() { | |
svar = "haha"; | |
} | |
@Override | |
public String toString() { | |
return String.format("F={%s}", svar); | |
} | |
} | |
class G { | |
private final String ssvar; | |
public G() { | |
ssvar = "hahahaha"; | |
} | |
@Override | |
public String toString() { | |
return String.format("G={%s}", ssvar); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment