Search code examples
javastack-overflow

Java - StackOverflowError - access HashMaps


I am getting a java.lang.StackOverflowError when attempting to call a method within another class.

I think the problem is due to each class being instantiated within each other but I'm not sure as to why it causes this error or how to fix it.

Method call from Main():

    nexaConnect.returnAllChronologicalByRoom("bathroomSensorMappings");

Logic():

public class Logic {
  private SensorMaps mapAccess = new SensorMaps();

  void returnAllChronologicalByRoom(String room) {
    System.out.print(mapAccess.returnMap(room).get(0));
  }
}

SensorMaps:

public class SensorMaps {
  private Logic sensorConnect = new Logic();

  HashMap<Integer, String> returnMap(String mapChoice) {
    return MapRegistry.find(mapChoice);
  }
}

There is a third MapRegistry class but I don't think this is causing issues but I'll include it for completeness:

MapRegistry:

class MapRegistry {
  static Map<String,HashMap<Integer,String>> allMaps = new HashMap<>();

  static void register(String name, HashMap<Integer,String> myMap) {
    allMaps.put(name, myMap);
  }

  static HashMap<Integer,String> find(String name) {
    return allMaps.get(name);
  }
}

The two key lines in the error output:

at com.company.SensorMaps.<init>(SensorMaps.java:11)
at com.company.Logic.<init>(Logic.java:19)

Refer to lines:

private Logic sensorConnect = new Logic();
private SensorMaps mapAccess = new SensorMaps();

The full error output:

Exception in thread "main" java.lang.StackOverflowError
    at com.company.SensorMaps.<init>(SensorMaps.java:11)
    at com.company.Logic.<init>(Logic.java:19)
    at com.company.SensorMaps.<init>(SensorMaps.java:11)
    at com.company.Logic.<init>(Logic.java:19)
    ...
    at com.company.SensorMaps.<init>(SensorMaps.java:11)
    at com.company.Logic.<init>(Logic.java:19)

Solution

  • Your Logic class creates an instance of SensorMaps whenever it is instantiated.

    private SensorMaps mapAccess = new SensorMaps();
    

    Your SensorMaps class creates an instance of Logic whenever it is instantiated.

    private Logic sensorConnect = new Logic();
    

    Hence, whenever you create an instance of one of these two classes, you get into an infinite loop that ends in StackOverflowError.

    You should re-consider your logic, and eliminate at least one of these instance variables (or change on of them to a static variable if it makes sense).

    I don't see where you are using sensorConnect, so I don't know if it's necessary.