shar
shar

Reputation: 2078

Arrays are reified in Java

I recently came across that, Arrays are reified in Java. That is, they know the type information only during run time. But I am a little confused with this definition.

If Arrays are said to know the type information only during runtime, I should literally be able to assign any values to any arrays, since the typing is known only at run time and errors will be thrown at run time only. But that is not the case in real time. We get a compile time error for that.

So can someone throw light on "what does it mean by - arrays are reified"?

Upvotes: 8

Views: 2362

Answers (4)

akhil_mittal
akhil_mittal

Reputation: 24157

As mentioned in doc:

A reifiable type is a type whose type information is fully available at runtime. This includes primitives, non-generic types, raw types, and invocations of unbound wildcards.

Non-reifiable types are types where information has been removed at compile-time by type erasure — invocations of generic types that are not defined as unbounded wildcards. A non-reifiable type does not have all of its information available at runtime. Examples of non-reifiable types are List and List; the JVM cannot tell the difference between these types at runtime. As shown in Restrictions on Generics, there are certain situations where non-reifiable types cannot be used: in an instanceof expression, for example, or as an element in an array.

So Arrays are reified and covariant but generics are invariant and type-erased by nature. Arrays provide runtime type safety and throw ArrayStore exception if element of correct type is not added.

Upvotes: 1

Michael Berry
Michael Berry

Reputation: 72284

If Arrays are said to know the type information only during runtime, I should literally be able to assign any values to any arrays, since the typing is known only at run time errors will be thrown at run time only. But that is not the case in real time. We get a compile time error for that.

Reifiable types know their type at runtime and compile time, which is why the compiler will still prevent you making silly mistakes where it can (what's the point in letting them through?)

However, there's times when the compiler can't always work out for certain whether an assignment (for instance) will be valid because it doesn't know the exact types, and this is where reified types can check. For instance:

Object[] arr = new String[5];
arr[0] = 7;

...this will compile, because on the second line the compiler only knows the static type of the array as Object, whereas the dynamic type is something more specific. It will fail as an exception at Runtime, which it can only do because (unlike with the generic collection classes) the specific type is known at runtime.

Upvotes: 3

Kevin Bowersox
Kevin Bowersox

Reputation: 94429

I believe the term you are looking for is reifiable.

A reifiable type does not lose any type information due to type erasure at runtime. Examples of reifiable types include:

  • primitives
  • non-generic reference types
  • arrays or primitives or arrays of non-generic reference types.

Reifiable does not mean a type is not known at compile time. What this does mean is that something like the following, cannot be typed checked:

List<Integer>[] myList;

Arrays carry runtime information about the types they store. Non-refiable types cannot be type checked at runtime, which does not make them good candidates for the component type of an array.

When using reifiable types as the component type of an array such as String[] the complete type information is available at runtime, so type checks can be performed.

String[] someArray = new String[2];
//some factory returns Integer upcasted to Object
someArray[0] = someFactory.getType("Integer");  //throws RuntimeException

Sources:

http://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ106 (Good)

Upvotes: 7

JB Nizet
JB Nizet

Reputation: 691695

What I think that means is that the given lines of code will throw an exception:

String[] arrayOfStrings = new String[10];
Object[] arrayOfObjects = arrayOfStrings; // compiles fine
arrayOfObjects[0] = new Integer(2); // throws a runtime exception (ArrayStoreException IIRC)

Arrays are covariant: String[] extends Object[]. But the actual type of the array is known at runtime, and an attempt to store an instance which is not of the right type throws an exception.

Upvotes: 10

Related Questions