0

I was reading about generics and type safety and found that arrays cannot be generic in java. I also understood the covariant nature of arrays which directed me to the array store exception. I understand why this exception occurs.

I tried the below code

class SuperClass {
    
}

class SubClass extends SuperClass {
    
}
public class ArrayCheck {
    
    public static void main (String args[]) {   
        SubClass arr[] = new SubClass[10];
        
        arr[0] = new SubClass();
        
        SuperClass[] arr1 = arr;
        arr1[1] = new SuperClass();
        
    }
}

This gives an ArrayStoreException as expected. My questions are

  1. My question is how does JVM check for array types at runtime? Does the compiler append any additional code or is there some predefined process that JVM follows before executing instructions?

  2. At what point this exception was raised? I thought that the ArrayStoreException would only occur if I try to read the array but I was wrong. So I am not understanding at what point exactly this error was raised.

Also, need a bit of clarification on the Java program execution process.

  1. Are run time errors and exceptions only the errors that occur while the program is in execution i.e JVM has started interpreting and executing the instructions or an error during bytecode verification is also considered run time error.
user207421
  • 305,947
  • 44
  • 307
  • 483
Asim
  • 413
  • 1
  • 4
  • 13
  • 1
    You get `ArrayStoreException` when you try to *store* something into the *array* (because you attempt to store an invalid element into the array), you'll get a `ClassCastException` when you try to *read* something from the *array* (because it implicitly casts the element in the array into the receiver type). Regarding the errors: [What is the difference between run-time error and compiler error?](https://stackoverflow.com/q/9471837/5515060) – Lino Sep 09 '20 at 07:13
  • https://docs.oracle.com/javase/specs/jls/se14/html/jls-10.html#jls-10.5 – Andy Turner Sep 09 '20 at 07:14
  • @Lino Thank you for the reply. So I guess errors during bytecode verification are also runtime errors. Basically anything after compilation is run time. This clarifies the error part. I need some more clarification on the first 2 questions. I understood that while reading I get ClassCastException, now I need to know at what point during the runtime JVM does the verification for array types and how? Is there some sequence that JVM follows or JVM checked it when it reached to the instruction where I assigned an invalid value to my array. Is there a technical word for this type of checking? – Asim Sep 09 '20 at 07:26
  • 1
    @Asim Now I'm only assuming because the specs I've seen only mention that the exception **will** be thrown, but not at which point. Because the logic of the array accessing is not implemented in java, but on a lower level, the check must be thrown in the "`native`-layer" (just not java-code). Also regarding your question about array-types, this is the only thing I've found (https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.8), though I haven't searched that far. Maybe also [this](https://www.geeksforgeeks.org/array-primitive-type-object-java/) helps – Lino Sep 09 '20 at 07:36
  • 3
    Hint: as soon as you start numbering independent subquestions within your question ... you are getting it wrong. The idea is that your questions here ... contain **one** question, not multiple. – GhostCat Sep 09 '20 at 08:32
  • 1
    I don't get why people make up things in their mind or read questionable articles instead of starting with the official authoritative source. From [the documentation of `ArrayStoreException`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/ArrayStoreException.html): “Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. For example, the following code generates an ArrayStoreException: `Object x[] = new String[3]; x[0] = new Integer(0);`”. So how can you assume that the exception will be thrown at a read operation? – Holger Sep 10 '20 at 06:56
  • I assumed, I tried and I found I was wrong. I did read the document before posting it here. I got confused at with what point, which was related to the processing of the JVM. I don't know why people assume that everyone asking questions here hasn't read the document. Maybe you can ask that question on the portal itself. Hope you'll get an answer :D – Asim Sep 10 '20 at 07:33
  • 1
    I didn’t presume that you didn’t read it, I asked why *you didn’t start* with reading it, before making wrong assumptions and doing experiments. The documentation is clear and provides an example. So if you read it, why are you still asking “at what point” the exception will be thrown? Moreover, you have an example code that will produce such an exception and can look at the stack trace to see precisely, at which line number the exception has been thrown. So what’s the question? – Holger Sep 10 '20 at 08:42
  • @Holger, you are right. I didn't frame my question correctly. I could have avoided point 2 totally. The basic question was how does array type checking works at the JVM level. By "At what point" I wanted to understand at runtime what does JVM does to check this kind of errors. I assumed it would be while reading but I read the document and got to know it was at the assigning incorrect value but I didn't understand how at this very line it would know about the wrong assignment so it must have started checking and maintained some status of the array from the beginning. But anyway thanks! – Asim Sep 11 '20 at 05:04
  • I don't know if editing it now would be a good idea because people mentioned that question in their answers. So I will leave it as it is so that other viewers don't get confused. – Asim Sep 11 '20 at 05:06

1 Answers1

4

My question is how does JVM check for array types at runtime ?

When the JVM is interpreting bytecodes, the interpreter performs the relevant runtime type checks when interpreting the aastore bytecode instruction. The relevant JVM spec link is https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.aastore.

The JIT compiler will translate the aastore instruction into native code that does the same thing, though it may optimize away any type checks that it can determine to be redundant.

Note this kind of thing would only come to the verifier's attention if you tweaked the bytecodes to attempt to assign a reference into an array of a primitive type.

At what point this exception was raised?

When you assign a value into an array of some reference type and the value you are assigning is not assignment compatible with the base type of the array.

(Note that the exception won't be thrown for arrays of primitive types. If you try to assign a long into an int[] or a boolean into an int[] you will get a compilation error. If you try to assign an int into a long[] the value will be widened.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216