4

It is an example in the book Core Java

Two class Employee and Manager. Manager extends Employee. The code below

Manager[] mans ={new Manager("Adam"),new Manager("Ben")};              
Employee[] emps =mans ;   
emps[0] = new Employee ("Charlie");//throws ArrayStoreException in runtime actually;

The author said that in this situation the elements in arrays SHOULD REMAIN THE SAME TYPE or it throws ArrayStoreException. In my mind emps[0] is just a reference to instance 'new Employee ("Charlie")' and type of emps[0] is Employee declared before.So why it throws exception.Is there something wrong with my basics?

1
  • emps is of type Manager[] and emps[0] is expected to be of type Manager. Commented Jun 13, 2014 at 14:05

3 Answers 3

4

When array is created it remembers what type of data it is meant to store. So if you have classes

class Employee { .. }
class Manager extends Employee { .. }

and you will create array

Manager[] arrM = new Manager[10];

array will remember that it need to store only instances of Manager class or its derived types. But such array can't store super type of Manager since super type may not have all methods or fields of Manager class so something like

arrM[0] = new Manager();

is OK, but

arrM[0] = new Employee();

throws java.lang.ArrayStoreException: Employee pointing that Employee is not correct argument here.

So in your case you are

  • creating array for Managers

    Manager[] mans ={new Manager("Adam"),new Manager("Ben")};
    
  • creating reference to this array using its super-type Employee

    Employee[] emps =mans;
    

    (but this reference it still pointing to array which can hold only Menagers)

  • and trying to place into array new Employee

    emps[0] = new Employee("Charlie");
    

but as I mentioned this can't be allowed because it is possible that Employee do not have same members as Manager. Lets say Menager can hire(...) someone, while Employee can't (doesn't have this method). What would happen if you would call

    mans[0].hire(new Employee("Tom");

and emps[0] = new Employee ("Charlie"); would not throw exception but would let you place Employee in emps[0]? Since mans and emps are using same array it would mean that mans[0].hire(new Employee("Tom") would be called from Employee("Charlie") which can't hire anyone because Employee don't have hire method.

That is why you can't place instance of super-type (Employee) in array of Managers.

Sign up to request clarification or add additional context in comments.

8 Comments

Very detailly.Thank you very much!It's interesting that if the code like Manager man = new Manager("Tom"); Employee emp = man; emp=new Employee("Alex"); at the end man.getName() is still Tom.
Actually in Employee emp = man; you are creating new reference which will hold same object as man. When you do emp=new Employee("Alex"); you are just assigning different value to this new reference, so you are not affecting man reference.
Is it different refer mechanism between normal object and elements in arrays?The normal reference can change refered object but the arrays reference can't change refered object casually after original assignment.The arrays is more strict i think
I am not sure what you mean by different. If you want man to print Alex then you shouldn't use emp=new Employee("Alex"); but emp.setName("Alex"); because you want to affect object which was storing "Tom", as I said earlier by emp=new Employee("Alex"); you are affecting only emp reference and make it store new Employee with name Alex. This approach just points emp to new employee, it doesn't make men to also point to Alex.
"normal reference can change refered object but the arrays reference can't change refered object" no, you can change refereed object in array, it just has to be object that array expects.
|
0

On second line you can assign an array of subclass (Manager [] mans) to a reference to an array of superclass (Employee[] emps). No problems on that... but after this line the real type of emps is

Manager[]

The real type of the array is determined at run-time and it is worth nothing it is referenced by a reference to Employee[], it sitll is an array of Manager.

So emps[0] is expected to be of type Manager.

3 Comments

It's know at compile time, so why there is runtime exception ?
Compilers doesn't know as much as it could know... if(false){ System.out.println("a"); } will give a wrning, if(1==2+2){ System.out.println("a"); } will not...
Moreover this is a trivial example, it will not possible to tell in this case: Employee[] emps = someFucntionReturningArray()
0

It throws an exception because, like the book says, the types are different. Employee[] emps = mans; means that emps has two elements in it with type Manager. So if you add a new element or replace an existing element, it must be the same type.

I wonder if you made an array mans with size 1 (don't know what you would do this, maybe an ArrayList if you're planning to expand it later) and then followed the rest of your code, what would happen. I bet it would still not let you insert an Employee into the array.

3 Comments

i dont understand what you mean with making arrays size 1 by ArrayList. But it's ok without exception if using ArrayList to declare mans .
I don't mean you have to use an ArrayList to make it size 1, just that an array of size 1 is pointless because it's a fixed size, so it's really just a single object or primitive data type. An ArrayList however will let you add things to it, so making a size 1 ArrayList is not pointless.
in this case the exception still exist.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.