Last active
September 13, 2018 14:41
-
-
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
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
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()); | |
} | |
} |
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
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"); | |
} | |
} |
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
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(); | |
} | |
} | |
} |
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
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; | |
} | |
} |
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
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note the reflection invocation is slower than compiled method invocation, which is optimized.