Search code examples
javaarraysprivate-constructor

Index 0 out of bounds for length 0 — why?


This code works:

class Test {
    static int size;
}

public class E08_ConnectionApp {
    public static void main(String[] args) {
        Test.size = Integer.parseInt(args[0]);
        Test[] test = new Test[Test.size];
        for (int i = 0; i < Test.size; i++) test[i] = new Test();
    }
}

But when I do THE SAME for other classes, I get the error from the title. I don't understand what's wrong. Please, tell me.

This code doesn't work:

class Connection {
    private int ID;

    private Connection(int ID) {
        this.ID = ID;

        print("Connection number " + ID + " created.");
    }

    static Connection createNewConnection(int ID) { return new Connection(ID); }

    Connection getConnection() { return this; }

    public int getID() {
        return ID;
    }
}
class ConnectionManager {
    private int size;

    public ConnectionManager(int size) {
        this.size = size;

        for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);
    }

    private Connection[] connections = new Connection[size];

    public Connection getAvailableConnection() {
        for (int i = 0; i < size; i++)
            if (connections[i] != null) {
                Connection temp = connections[i].getConnection();
                connections[i] = null;
                print("Connection #" + temp.getID() + " fetched.");
                return temp;
            }

        print("No connections available...");
        return null;
    }
}

public class E08_ConnectionApp {
    public static void main(String[] args) {
        ConnectionManager connectionManager = new ConnectionManager(Integer.parseInt(args[0]));
    }
}

When debugging, I get an error from the title in this line:

for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);

I'm 95% sure that this error is because connections, although has space allocated for it (an array of size 5, which is an argument of the program), contains null references to Connection objects. But what I'm trying to do is actually initialize this array, to attach array references to actual objects. If I'm doing it wrong, what is the right way?

I'm thinking about some bad settings in my project or maybe IntelliJ IDEA bug, but the latter is highly unlikely.

Thanks in advance for your answers.

I tried google the error and thinking for myself, I tried various ways to reproduce the problem, but in Test everything works as expected...


Solution

  • It is simply because the array was created before your constructor:

    class ConnectionManager {
        private int size;
    
        // you tried to create array with size, for which is not initialised yet, 
        // which is 0 for int instance variable
        private Connection[] connections = new Connection[size];  
    
    
        public ConnectionManager(int size) {
            this.size = size;  // this assignment happens after your array creation
            for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);
        }
    
     
    

    (Rearranged the code slightly)

    Those initialisation statements (e.g. private Connection[] connections = new Connection[size];) are performed before your Constructor logic. Which means, when it tried to create the connections array, size is still 0, hence the array is created with 0 size.

    The proper way is

    class ConnectionManager {
        private int size;
        private Connection[] connections;
    
    
        public ConnectionManager(int size) {
            this.size = size;  // this is actually superfluous. 
                               // You can always get it directly from array's size
            this.connections = new Connection[size];
    
            for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);
        }