How to resolve a "java.lang.InstantiationException"?

Brian Var picture Brian Var · Mar 22, 2015 · Viewed 45.6k times · Source

I'm parsing in an XML file using SAX but when I call the class loader on the class, a java.lang.InstantiationException is thrown.

I debugged this by the reason for the exception, 'Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or is an abstract class.'

But the location class isn't an interface or abstract class. I've also checked that the class is in the correct package and it is.

Does anyone have any idea why the exception is being thrown in this case?

The exception is being thrown just after the first println in the startElement of the Parser class:

public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        if (qName.equals("location")){
            location = true;

            System.out.println("Found a location...");
            //exception thrown after this statement as shown
            //in the error output below
            try {
                //Read in the values for the attributes of the element <location>
                int locationID = Integer.parseInt(atts.getValue("id"));
                String locationName = atts.getValue("name");

                //Generate a new instance of Location on-the-fly using reflection. The statement Class.forName("gmit.Location").newInstance(); invokes the 
                //Java Class Loader and the calls the null (default) constructor of Location.
                Location loc = (Location) Class.forName("gmit.Location").newInstance();
                loc.setId(locationID); //Now configure the Location object with an ID, Name, Description etc...
                loc.setName(locationName);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }else if (qName.equals("description")){
            description = true;
            System.out.println("Found a description. You should tie this to the last location you encountered...");
        }else if (qName.equals("exits")){
            exits = true;
            System.out.println("Found an exit. You should tie this to the last location you encountered...");
        }else if (qName.equals("item")){
            item = true;
            System.out.println("Found an item. You should tie this to the last game-character you encountered if the boolean gameCharacter flag is true...");
        }else if (qName.equals("game-character")){
            gameCharacter = true;
            System.out.println("Found a game character...");
        }else if (qName.equals("search-algorithm")){
            searchAlgorithm = true;
            System.out.println("Found a search algo. You should tie this to the last game-character you encountered if the boolean gameCharacter flag is true...");
        }
    }

My complete location class:

http://hastebin.com/yofuyafipe.java

The errors being thrown during run time:

http://hastebin.com/jonozeyefe.avrasm

Answer

Stephen C picture Stephen C · Mar 22, 2015

Your Location class does not have a no-args constructor. (It has two constructors with declared arguments ... so there is no default no-args constructor.)

Solutions:

  • Add a no-args constructor.
  • Reflectively lookup one of the Constructor objects on the Location Class object and invoke it using Constructor.newInstance(...) with arguments that give the actual constructor argument values.

It looks like the first option is the better one in this context ... 'cos it looks like you don't have the required argument values at that point in the code.