Skip to content

Instantly share code, notes, and snippets.

@rupert-ong
Last active September 13, 2018 14:41
Show Gist options
  • Save rupert-ong/93f022a9147b3d710e1231a937579995 to your computer and use it in GitHub Desktop.
Save rupert-ong/93f022a9147b3d710e1231a937579995 to your computer and use it in GitHub Desktop.
Java Runtime Reflection: Accessing and Invoking Members #java #runtime #reflection #members #invocation
package com.ps;
import com.ps.finance.BankAccount;
public class AccessTypeClassInstance {
public static void main(String[] args) {
// Class instance from Type Reference
BankAccount acct = new BankAccount("1234");
doWork(acct);
// Class instance from String Name
try {
Class<?> c = Class.forName("BankAccount");
showName(c);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// Class instance from Type Literal
Class<BankAccount> c = BankAccount.class;
showName(c);
// All 3 examples point to the exact same Class instance
}
private static void doWork(Object obj) {
Class<?> c = obj.getClass();
showName(c);
}
private static void showName(Class<?> theClass) {
System.out.println(theClass.getSimpleName());
}
}
package com.ps;
import com.ps.finance.HighVolumeAccount;
import java.lang.reflect.Modifier;
public class AccessTypeInformation {
public static void main(String[] args) {
HighVolumeAccount acct = new HighVolumeAccount("5678");
classInfo(acct);
typeModifiers(acct);
}
private static void classInfo(Object obj) {
Class<?> theClass = obj.getClass();
System.out.println(theClass.getSimpleName());
Class<?> superClass = theClass.getSuperclass();
System.out.println(superClass.getSimpleName());
Class<?>[] interfaces = theClass.getInterfaces();
for (Class<?> theInterface : interfaces)
System.out.println(theInterface.getSimpleName());
}
private static void typeModifiers(Object obj) {
Class<?> theClass = obj.getClass();
int modifiers = theClass.getModifiers();
if (Modifier.isFinal(modifiers))
System.out.println("Class is final");
if(Modifier.isPrivate(modifiers))
System.out.println("Class access modifier is private");
else if(Modifier.isProtected(modifiers))
System.out.println("Class access modifier is protected");
else if(Modifier.isPublic(modifiers))
System.out.println("Class access modifier is public");
}
}
package com.ps;
import com.ps.finance.BankAccount;
import com.ps.finance.HighVolumeAccount;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class AccessTypeMemberAndMethodInformation {
public static void main(String[] args) {
// Get field information
BankAccount acct = new BankAccount("1234", 500);
fieldInfo(acct);
// Get method information
HighVolumeAccount acct2 = new HighVolumeAccount("4567");
methodInfo(acct2);
// Call method
callGetId(acct);
callDeposit(acct, 50);
System.out.println("Balance: " + acct.getBalance());
}
private static void fieldInfo(Object obj) {
Class<?> theClass = obj.getClass();
// Get only public, declared or inherited fields (won't show)
System.out.println("Get public, declared or inherited fields:");
Field[] fields = theClass.getFields();
displayFields(fields);
// Get private, protected or public declared fields
System.out.println("Get declared fields:");
Field[] declaredFields = theClass.getDeclaredFields();
displayFields(declaredFields);
}
private static void methodInfo(Object obj) {
Class<?> theClass = obj.getClass();
// Get only public, declared or inherited methods
Method[] methods = theClass.getMethods();
System.out.println("Get public, declared or inherited methods:");
displayMethods(methods);
// Get private, protected or public declared methods
System.out.println("Get declared methods:");
Method[] declaredMethods = theClass.getDeclaredMethods();
displayMethods(declaredMethods);
}
private static void displayFields(Field[] arr) {
for (Field f : arr)
System.out.println(f.getName() + " : " + f.getType());
}
private static void displayMethods(Method[] arr) {
for (Method m : arr)
if(m.getDeclaringClass() != Object.class)
System.out.println(m.getName());
}
public static void callGetId(Object obj) {
try {
Class<?> theClass = obj.getClass();
Method m = theClass.getMethod("getId");
Object result = m.invoke(obj);
System.out.println("Result: " + result);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void callDeposit(Object obj, int amt) {
try {
Class<?> theClass = obj.getClass();
Method m = theClass.getMethod("deposit", int.class);
m.invoke(obj, amt);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
package com.ps.finance;
public class BankAccount {
private String id;
private int balance;
public BankAccount(String id) {
this.id = id;
}
public BankAccount(String id, int balance) {
this.id = id;
this.balance = balance;
}
public String getId() {
return id;
}
public synchronized int getBalance() {
return balance;
}
public synchronized void deposit (int amount) {
this.balance += amount;
}
public synchronized void withdraw (int amount) {
this.balance -= amount;
}
}
package com.ps.finance;
public final class HighVolumeAccount extends BankAccount implements Runnable {
public HighVolumeAccount(String id) { super(id); }
public HighVolumeAccount(String id, int balance) { super(id, balance); }
private int[] readDailyDeposits() {
return new int[100];
}
private int[] readDailyWithdrawals() {
return new int[100];
}
@Override
public void run() {
for(int depositAmt : readDailyDeposits())
deposit(depositAmt);
for(int withdrawalAmt : readDailyWithdrawals())
withdraw(withdrawalAmt);
}
}
@rupert-ong
Copy link
Author

rupert-ong commented Sep 13, 2018

  • Access the class type of any (unknown or dynamic) instance at runtime
  • Get information about any declared and/or inherited members, fields and methods, as well as their access modifiers
  • Invoke methods

Note the reflection invocation is slower than compiled method invocation, which is optimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment