Reputation: 12242
In computing, reification has come to mean an explicit representation of a type—that is, run-time type information.
oracle tutorials says ,
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 type is reifiable if it is one of the following:
- A primitive type (such as
int
) //understood- A nonparameterized class or interface type (such as
Number
,String
, orRunnable
) // why- A parameterized type in which all type arguments are unbounded wildcards (such as
List<?>
,ArrayList<?>
, orMap<?, ?>
) // why- A raw type (such as
List
,ArrayList
, orMap
) // why- An array whose component type is reifiable(such as
int[]
,Number[]
,List<?>[]
,List[]
, orint[][]
) // why
A type is not reifiable if it is one of the following:
- A type variable(such as
T
) // why- A parameterized type with actual parameters (such as
List<Number>
,ArrayList<String>
, orMap<String, Integer>
) // why- A parameterized type with a bound (such as
List<? extends Number>
orComparable<? super String>
) // why
Why 2,3,4,5 is reifiable and 6,7,8 as non-reifiable?
Upvotes: 50
Views: 13095
Reputation: 471
Sun/Oracle says the reason is combo of:
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
In short, 1-5 are reifiable because they simply remain the same types as specified in the code so there is no type information lost/erased, but 6-8 will lose type information during compilation (the stuff between the <>) so can't be accessed at runtime.
Upvotes: 23
Reputation: 5458
Java originally implemented reflection in version 1.1.
Generic classes were introduced in version 5.0.
When introducing generics it was decided that for backwards compatibility reasons the generic type information will be erased at runtime. This allowed code that was written pre generics to operate with generics based code without modification.
For example a List[Integer32]
would be translated by the compiler to Integer32[]
.
All type checks would be done at compile time, and if anything was missed it would generate a runtime error.
This implementation detail meant that generics were not reified (there is no specific implementation of them in the VM) and therefore whenever one would try to reflect the generic type the returned information would be that of the underlying type. Another reason why this would be advantageous is because no implementations for the reified types would have to be emitted by the VM whenever one was used (in c# for instance, whenever you use a generic type it's actual implementation is generated by the VM at runtime, along with the reflection metadata, thus having a performance hit whenever a new type needed to be generated).
Upvotes: 2
Reputation: 1
Just an educated guess, but I suspect the key to understanding this is to recognize that while Java is a strongly typed language and verifies type references as part of the compilation process, in many cases the type information is not actually needed to execute the logic. In that case, the generated bytecode may know that it is working with an instance of an Object, but not know the type. That would especially make sense given that languages that do not use strong typing can be generated as java bytecode. So if the object type has been dropped, the instance would be non-reifiable.
Upvotes: 0
Reputation: 18702
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<String> and List<Number>; 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.
Upvotes: 8
Reputation: 547
Understand the meaning of this two terms.
Reifiable means whose type is fully available at run time means java compiler do not need any process of type erasure.
Non-Reifiable means java compiler needs type erasure process because type is not fully available.
A type is reifiable if it is one of the following:
1. A primitive type (such as int) :
Here think that when you write or use any int as a reference, do you think that compiler needs any process for identification for the type of int? no because int is int.... same for all primitive type
2. A nonparameterized class or interface type (such as Number, String, or Runnable)
same answer as i told in previous answer that compiler do not need any type erasure for Number, String, or Runnable.
3. A parameterized type in which all type arguments are unbounded wildcards (such as List<?>, ArrayList<?>, or Map<?, ?>)
All unbounded wildcard are accepted as reifiable type because it is already mention in definition of reifiable type, now it is up to the API developer why they consider it as a reifiable type.
4. A raw type (such as List, ArrayList, or Map) ::
same answer as first question
5. An array whose component type is reifiable(such as int[], Number[], List<?>[], List[], or int[][]) ::
same answer as first question
A type is not reifiable if it is one of the following:
6. A type variable(such as T) :
Because java can not identify the type of T, Compiler needs type erasure to identify the type.
7. A parameterized type with actual parameters (such as List<Number>, ArrayList<String>, or Map<String, Integer>):
Here all type is a generic type, at runtime compiler see List as List ... so as per definition of Non-refiable all these collection are consider as a non reifiable.
8. A parameterized type with a bound (such as List<? extends Number> or Comparable<? super String>).
same answer as previous one
Upvotes: 17
Reputation: 21
I'm not entirely sure I understand your question, but you might be referring to object types as opposed to primitive types. That question is all the more important as primitive types such as int or double cannot be used as generic types -- hence their wrapping classes such as Integer.
// This won't work
ArrayList<int> list = new ArrayList<int>();
// But this will
ArrayList<Integer> list = new ArrayList<Integer>();
To sum it up I'd say all objects -- and only objects -- are reifiable. (And therefore usable as generic types instantiation)
Upvotes: -1
Reputation: 11577
you could ask google the same question:
reifiable type
When you use generics, much of the time, compile-time type information is lost. At run time, often all the program knows about a reference is that is a reference to some sort of Object. If all the type information is also known at run time, the type is called reifiable. Perhaps some day generics will be redesigned so that all types are reifiable.
Upvotes: 9