Java Reflections cheatsheet for processing

Hi I am trying to create a cheatsheet for most things reflections in java, however I am currently struggling with some aspects of the code.

Please note the code is not mine, original code can be found here.


and here
http://www.newthinktank.com/2012/09/java-reflection-video-tutorial/

the code in the video is paired with a list of classes which can be found here
http://www.newthinktank.com/2012/09/abstract-factory-design-pattern/

however if you want one easy to download file then its on my github

now


//import java.lang.reflect.Constructor;
//import java.lang.reflect.Field;
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//import java.lang.reflect.Modifier;
void test(){
    
    Class reflectClass = Button.class;
    
    // Get the class name of an Object
    
    String className = reflectClass.getName();
    
    System.out.println(className + "\n");
    
    // Check modifiers of a class
    // isAbstract, isFinal, isInterface, isPrivate, isProtected,
    // isStatic, isStrict, isSynchronized, isVolatile
    
    int classModifiers = reflectClass.getModifiers();
    
    System.out.println("Modifier " + Modifier.isPublic(classModifiers) + "\n");
    
    // You can get a list of interfaces used by a class
    // Class[] interfaces = reflectClass.getInterfaces();
    
    // Get the super class for Button
    
    Class classSuper = reflectClass.getSuperclass();
    
    System.out.println(classSuper.getName() + "\n");
    
    // Get the objects methods, return type and parameter type
    
    Method[] classMethods = reflectClass.getMethods();
    
    for(Method method : classMethods){
      
      // Get the method name
      
      System.out.println("Method Name: " + method.getName());
      
      // Check if a method is a getter or setter
      
      if(method.getName().startsWith("get")) {
        
        System.out.println("Getter Method");
        
      } else if(method.getName().startsWith("set")) {
        
        System.out.println("Setter Method");
        
      }
      
      // Get the methods return type
      
      System.out.println("Return Type: " + method.getReturnType());
      
      Class[] parameterType = method.getParameterTypes();
      
      // List parameters for a method
      
      System.out.println("Parameters");
      
      for(Class parameter : parameterType){
        
        System.out.println(parameter.getName());
        
      }
      
      System.out.println();
    
    }
    
    // How to access class constructors
    
    Constructor constructor = null;
    
    Object constructor2 = null;
    
    try {
      
      // If you know the parameters of the constructor you
      // want you do the following.
      
      // To return an array of constructors instead do this
      // Constructor[] constructors = reflectClass.getConstructors();
      
      // If the constructor receives a String you'd use the
      // parameter new Class[]{String.class}
      // For others use int.class, double.class, etc.
      
      constructor = reflectClass.getConstructor(new Class[]{Menu.class});
      
      // Call a constructor by passing parameters to create an object
      
      constructor2 = reflectClass.getConstructor().newInstance(20,20,20,20,"test");
    } 
    catch (NullPointerException e) {
      // Exceptions thrown
      e.printStackTrace();
    }catch (NoSuchMethodException e) {
      // Exceptions thrown
      e.printStackTrace();
    }catch(SecurityException e){
    
    }catch (InstantiationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    
    // Return the parameters for a constructor
    Button Btn = null;
    
    Button Btn1 = null;
    
    float x = 20,y = 20, w = 20,h = 20;
    String label = "label";
    
    if(constructor!=null){
    Class[] constructParameters = constructor.getParameterTypes();
    
    for(Class parameter : constructParameters){
      
      System.out.println( parameter.getName());
      
    }
    
    //if(constructParameters.isempty){
      
    //}
    
    
    
    try {
      
      // Create a Button object by calling newInstance
      
      Btn = (Button) constructor.newInstance();
      
    } 
    catch (NullPointerException e) {
      
      e.printStackTrace();
      
    }
    catch (InstantiationException e) {
      
      e.printStackTrace();
      
    }
    catch (IllegalAccessException e) {
      
      e.printStackTrace();
      
    }
    catch ( IllegalArgumentException e) {
      
      e.printStackTrace();
      
    }
    catch ( InvocationTargetException e) {
      
      e.printStackTrace();
      
    }}
    
    // Now I can call methods in the Button Object
    if(Btn!=null){
    Btn.setName("text");
    
    String an = "hello";
    System.out.println("Button: " + Btn.label);
      }
    else{
      println("Btn = null");
    }
    // Access private fields using reflection
    
    // Field stores info on a single field of a class
    
    Field privateStringName = null;
    
    try {
      
      // Create a Button object
      
       Btn1 = new Button(200,200,20,20,"test");
      
      // Define the private field you want to access
      // I can access any field with just its name dynamically
      
      privateStringName = Button.class.getDeclaredField("label");
      
      // Shuts down security allowing you to access private fields
      
      privateStringName.setAccessible(true);
      
      // Get the value of a field and store it in a String
      
      String valueOfName = (String) privateStringName.get(Btn1);
      
      System.out.println("Button: " + valueOfName);
      
      // Get access to a private method
      // getDeclaredMethod("methodName", methodParamters or null)
      
      // Since I provide the method name as a String I can run any method 
      // without needing to follow the normal convention methodName()
      
      String methodName = "getPrivate";
      
      Method privateMethod = Button.class.getDeclaredMethod(methodName, null);
      
      // Shuts down security allowing you to access private methods
      
      privateMethod.setAccessible(true);
      
      // get the return value from the method
      
      String privateReturnVal = (String) privateMethod.invoke(Btn1, null);
      
      System.out.println("EnemyShip Private Method: " + privateReturnVal);
      
      // Execute a method that has parameters
      
      // Define the parameters expected by the private method
      
      Class[] methodParameters = new Class[]{Integer.TYPE, String.class};
      
      // Provide the parameters above with values
      
      Object[] params = new Object[]{new Integer(10), new String("Random")};
      
      // Get the method by providing its name and a Class array with parameters
      
      privateMethod = Button.class.getDeclaredMethod("getOtherPrivate", methodParameters);
      
      // Shuts down security allowing you to access private methods 
      
      privateMethod.setAccessible(true);
      
      // Execute the method and pass parameter values. The return value is stored
      
      privateReturnVal = (String) privateMethod.invoke(Btn1, params);
      
      System.out.println("EnemyShip Other Private Method: " + privateReturnVal);
      
    }   
    
    catch (NoSuchFieldException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
    catch ( SecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    
    catch (IllegalArgumentException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
    
    catch (IllegalAccessException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
    
    catch (NoSuchMethodException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
    
    catch (InvocationTargetException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    
    noLoop();
}

//-------------button class-----------

class Button{
  
  Float x,y,w,h;
  String Label;
  
  Button(float xx, float yy, float ww,float hh, String Label){
    
  }
  
  void setName(String a){
    label = a;
  }
  
  
  void getName(){
   return label; 
  }
}

my code is all inclusive and should be good to go.

The only thing I’m struggling with is this sections,

Constructor constructor = null;
    
    Object constructor2 = null;
    
    try {
      
      // If you know the parameters of the constructor you
      // want you do the following.
      
      // To return an array of constructors instead do this
      // Constructor[] constructors = reflectClass.getConstructors();
      
      // If the constructor receives a String you'd use the
      // parameter new Class[]{String.class}
      // For others use int.class, double.class, etc.
      
      constructor = reflectClass.getConstructor(new Class[]{Menu.class});
      
      // Call a constructor by passing parameters to create an object
      
      constructor2 = reflectClass.getConstructor().newInstance(20,20,20,20,"test");
    } 

In the original code, this works fine and its able to create constructor and constructor 2,

however in mine constructor always remains null, even after adding a constructor to my button class which takes another Class as its parameter.

Any help would be appreciated.
Thanks


please note the original code is java only and the processing code also makes use of the reflect library

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

1 Like

Having difficulty accessing private fields in my sketch even when using

field.setAccessible(true) ;

which seems to be the generally accepted method. So I have to put all the dynamic variables to public. I haven’t yet taken a serious look at the state of variables when declared and they always remain with whatever the default is, ie nothing no public no private no static or anything. Is there any reason this would cause a serious problem to the program?

Almost all fields inside “.pde” files are prefixed w/ public if they don’t have 1.

Take notice that Class::getField() method can’t “see” non-public fields:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#getField(java.lang.String)

For a non-public field we’ve gotta use Class::getDeclaredField() instead over its original class or interface:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#getDeclaredField(java.lang.String)

1 Like

what are the normal circumstances in which one would choose public over private, just reading the java forums briefly, it seems to recommend keeping things private as often as possible.

1 Like

For “.pde” files, just ignore the access keywords unless something really needs to be public. :male_detective:

Processing’s IDE (PDE) is setup very differently compared to other IDEs. :astonished:

You’re gonna need to understand how the PDE’s preprocessor transpiles “.pde” files to actual “.java” in order to apply knowledge from the Java “world” back into Processing’s Java Mode. :coffee:

1 Like