3

I've been allocating arrays using the following syntax while going through some Java tutorials so far:

// Ok, all the elements are zero upon creation
int[] a = new int[5];

// I can set all the elements however I want!
for (int i = 0; i < a.length; i++)
     a[i] = i+1

But since when I started using a class, things have been confusing me:

class Employee
{
    public Employee(String name, int age) {
         emp_name = n;
         emp_age = a;
    }

    void setName(String name) {
          emp_name = name;
    }

    void setAge(int age) {
          emp_age = age;
    }

    private String emp_name;
    private String emp_age;

}

I use this class in the main function like the following:

Employee[] staff = new Employee[3];

This line should give me an array of three objects default initialized by the constructor as I assume.

When I do the following I get an exception on the runtime.

staff[0].setName("Test");

In C++, this has been be fairy simple which doesn't require an extra new:

Employee *e[3];

So, upon further searching something tells me that I still need to allocate memory for each of the elements in array to actually start using them. If so, then what was the purpose of using new operator? Doesn't it already allocate memory for the array? How come this doesn't happen with int array?

cpx
  • 17,009
  • 20
  • 87
  • 142
  • `Employee[] staff = new Employee[3];` is an array of Employee of size three that can hold three Employee instances. `int[] a = new int[5];` is an array of primitive integers that hold 5 int. No different you are just using them differently. – Shahzeb Jul 13 '15 at 23:05
  • Please remove the C++ tag, since your question isn't about C++, but Java. Java and C++ are different languages and handle arrays differently. – Thomas Matthews Jul 14 '15 at 00:22

3 Answers3

7

When you create an array of Objects, you create an array full of null objects. The array is full of "nothingness". An Employee will not be created until you explicitly create one.

Employee[] staff = new Employee[3];

At this point your array looks like:

[null] [null] [null]

You can then create an Employee by doing:

staff[0] = new Employee();

At this point, your default Employee constructor is called and your array now has an Employee object in the first position:

[Employee1][null][null]

Now that you have an actual Employee in the first position, you should be able to call:

staff[0].setName("Test");

Update:

In regard to the question:

what was the purpose of using new operator? Doesn't it already allocate memory for the array? How come this doesn't happen with int array?

Similar questions were already asked here and here. In short, when you create the array of Objects, you really create an array of references. At first, all these references just point to null objects. When you do staff[0] = new Employee();, you are in essence doing two things:

  1. Creating and allocating memory for a "new" Employee
  2. Telling staff[0] to now point to the new Employee object instead of null
Community
  • 1
  • 1
Tot Zam
  • 8,406
  • 10
  • 51
  • 76
4

In Java, all "objects" are actually just references (pointers, sort of). So you are correct in assuming that Java auto-initializes the values in the array, but in your second array, you have an array of references, which are basically memory addresses, and therefore are initialized to null.

You are getting your exception because you are calling a method on a null reference. Also, notice that when you created an array of primitives, you are using the assignment operator with the different indices in the array. In your example with objects, you are just immediately using the values in the array, not assigning them. So technically, what you were doing in the primitive array example can be done with object arrays, since it is simple assignment.

Adam Evans
  • 2,072
  • 1
  • 20
  • 29
  • Java uses references, not pointers. [There are differences](http://programmers.stackexchange.com/a/141838). – Turing85 Jul 13 '15 at 23:12
  • I know there are differences, but you can basically treat them the same, and since @cpx talked about c++ and pointers, I figured it would help him understand better to liken references to pointers. – Adam Evans Jul 13 '15 at 23:14
  • 1
    Especially if he/she is coming from a C/C++ background, it is not advised to use terms incorrectly. One might assume things, that are not true (e.g. "Pointer arithmetics and memory reinterpretion are possible"). – Turing85 Jul 13 '15 at 23:16
  • In C++, the purpose of `new` was always to allocate some memory. It confuses me a little to think about the statement `Employee[] staff = new Employee[3];` since its not allocating anything. It is only declaring an array without doing nothing about the memory. So, am I correct if I think it is just allocating an array of references since they live on the heap and therefore we use `new` operator? When I first looked at the code it seemed to me like as if I was creating a two dimensional array i.e. first the `new` operator for an array and then `new` for the each element in the array. – cpx Jul 14 '15 at 00:25
  • @cpx You are correct in thinking "it is just allocating an array of references since they live on the heap and therefore we use `new` operator". The statement `Employee[] staff = new Employee[3];` is telling the JVM "give me an array of references to Employee objects". Nowhere in there does the statement say to give you actual employees; you need to tell the JVM to do that in other statements. – Adam Evans Jul 14 '15 at 00:32
3

In Java, when you create an array of objects, the default values of every entry in the array is null. There are no constructors being called. You'll have to loop over the array and create an object for each entry.

for example

for(int i=0; i<staff.length; i++){
    staff[i] = new Employee("name" + i, 20);
}
Subler
  • 657
  • 6
  • 11