javaprocessingpde

How to print the contents of an instance in java or pde?


class bouncingBall():
    def __init__(self, bounce, window, position):
        self.bounce = bounce
        self.window = window
        self.position = position

ball = bouncingBall(0.35, 1.5, 0.75)
print(ball) # <__main__.bouncingBall object at 0x0000025980427D60>
print(ball.__dict__) # {'bounce': 0.35, 'window': 1.5, 'position': 0.75}

In python we can inspect the insides of an instance by using object.__dict__

How do we accomplish this in .java or .pde?


Solution

  • As Saksham(+1) points you, one option is to override toString(): this is manual, but it doesn't have the overhead of reflection.

    You can also use java.lang.reflect.*; which you could use for a utilty function in a superclass, then all your subclasses will inherit this trait (no need to manually override toString() for each subclass), however you will spend a bit of CPU time reflecting.

    Here's a very rough example demonstrating both:

    // option 2: reflect
    import java.lang.reflect.*;
    
    class BouncingBall{
    
      float bounce;
      float window;
      float position;
        
      BouncingBall(float bounce, float window, float position){
        this.bounce = bounce;
        this.window = window;
        this.position = position;
      }
      // option 1: override toString() (manual)
      String toString(){
        return String.format("[BouncingBall bounce=%.2f window=%.2f position=%.2f]", 
                                            bounce, window, position);
      }
    }
    
    void setup(){
      BouncingBall ball = new BouncingBall(0.35, 1.5, 0.75);
      println("ball properties and values via toString()");
      println(ball);
      println();
      
      println("ball properties and values via reflection");
      // reflect instance fields
      try{
        for(Field field : BouncingBall.class.getDeclaredFields()){
          println(field.getName(), field.get(ball));
        } 
      }catch(IllegalAccessException e){
        e.printStackTrace();
      }
    }
    

    Update In Python, it's nice you get a dict back which you can use further. In Java, in theory you could return a HashMap (or similar Map structure), however you can only associate keys of the same type. In this case, since all properties are float that would work, however you might have situations where the properties would be booleans, floats, ints, etc. A workaround for this could be using JSONObject: a nice side effect of this option is you could easily serialize/save the data to disk via saveJSONObject():

    import java.lang.reflect.Field;
    
    class BouncingBall{
    
      float bounce;
      float window;
      float position;
        
      BouncingBall(float bounce, float window, float position){
        this.bounce = bounce;
        this.window = window;
        this.position = position;
      }
      
      // option 1: override toString() (manual)
      String toString(){
        return String.format("{\"bounce\":%.2f, \"window\":%.2f, \"position\":%.2f}", 
                                 bounce, window, position);
      }
      // option 2: reflect
      JSONObject toJSON(){
        JSONObject result = new JSONObject();
        try{
          for(Field field : BouncingBall.class.getDeclaredFields()){
            // handle floats for demo purposes
            if(field.getType() == float.class){
              result.setFloat(field.getName(), (float)field.get(this));
            }
          } 
        }catch(IllegalAccessException e){
          e.printStackTrace();
        }
        return result;
      }
    }
    
    void setup(){
      BouncingBall ball = new BouncingBall(0.35, 1.5, 0.75);
      println("ball properties and values via toString()");
      println(ball);
      println();
      
      println("ball properties and values via reflection");
      println(ball.toJSON());
      
      // save JSON data
      saveJSONObject(ball.toJSON(), "ball.json");
    }
    

    (Notice the manual option of formatting toString() so the data is valid JSON also works (an can be saved to disk via saveStrings())

    Similarly you could use reflection to map loaded JSON data to instance properties should you need to.