Index 0 out of bounds for length 0 — why?

1.1k Views Asked by At

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...

3

There are 3 best solutions below

1
Adrian Shum On BEST ANSWER

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);
    }
0
CodeTheorist On

This error is happening in the latter 2 classes because they have constructors but doesn't occur on Test because it doesn't have a constuctor.

What this shows is that arg[0] is actually null or undefined, but it doesn't matter with Test as this value isn't actually being used in the constructor. In the latter 2 classes, the constructors are trying to assign null or undefined to a primitive int rather than an Integer, which can't be null, thus producing the error. As arg[0] is null or undefined, this shows that the app is actually being run without arguments. The only other problem may be if arg[0] is a string which can't be parsed as a number, but I'm pretty confident this would give you a parsing exception.

Please try running the app with an extra argument that can be parsed to an integer and see if the error still persists. This will tell you for sure if this is the case. Furthermore, you should add a constructor to Test to confirm this is the problem, as Test should throw the same exception if it has a constructor and this is indeed the correct error.

0
Rodney On

For a zero length array, no index value is valid.

This is no index 1, no index 0, no index anything.

for (int i = 0; i < Test.size; i++) test[i] = new Test();

This test doesn't throw because it iterates all the valid indecies of the test array, from zero to size-1. If size is zero the loop never runs.