presents: java reflection: the major changes from the ...khalid/.../jg-ch7-javareflection... ·...
Post on 04-Jul-2020
1 Views
Preview:
TRANSCRIPT
J ava Ref lec t ion
Michele OrrùMichele Orrù presents:
Java Reflection: the major changes from the introduction of Generics
taken in part from:Java Generics and CollectionsMaurice Naftalin & Philip Wadler
O'REILLY publications
J ava Ref lec t ion
Why Reflection?
J ava Ref lec t ion
Java Reflection transforms the classic static environment of a program in a
dynamic one, withgreat potentialities and benefits.
J ava Ref lec t ion
The main advantage is that with Reflection we can be able to write classes that are able to do dynamically introspection of their selves, at
runtime time:
➢ classes are loaded dynamically;➢ binding is done dynamically;
➢ object instances are created dynamically.
J ava Ref lec t ion
Some interesting features (http://java.sun.com):
➢ Invoke a method on an object, even if the method is not known until runtime.
➢ Create an instance of a class whose name is not known until runtime.
➢ Get and set the value of an object's field, even if the field name is unknown to the program until
runtime.
J ava Ref lec t ion
What's changed from the introduction of Generics?
J ava Ref lec t ion
With the advent of Generics:
➢ generics for reflection: generic types can now be used with reflection;
➢ reflection for generics: the introspection of the class can return
informations also about generics (with limitations).
J ava Ref lec t ion: g e n e r i c s f o r r e f l e c t i o n
A normal situation with reflection:
Class ki = Integer.class;Number n = new Integer(42);Class kn = n.getClass();assert ki == kn;
J ava Ref lec t ion: g e n e r i c s f o r r e f l e c t i o n
The same situation but with generics:
Class<Integer> ki = Integer.class;Number n = new Integer(42);
Class<? extends Number> kn = n.getClass();assert ki == kn;
The class Class from Java 5 can now take a type parameter: Class<T> is the type of
the class token for the type T.
J ava Ref lec t ion: g e n e r i c s f o r r e f l e c t i o n
Another example:
class Class<T> { public T newInstance(); public T cast(Object o); public Class<? super T> getSuperclass(); public <U> Class<? extends U> asSubclass(Class<U> n);
public <A extends Annotation> A getAnnotation(Class<A> n); public boolean isAnnotPresent(Class<? extends Annotation> n); ...}
J ava Ref lec t ion: g e n e r i c s f o r r e f l e c t i o n
Using the example before, and knowing that Retention is a subclass of Annotation, we can extract the retention annotation
on a class n as follows:
Retention r = n.getAnnotation(Retention.class);
J ava Ref lec t ion: r e f l e c t e d t y p e s a r e r e i f i a b l e t y p e s
With Reflection we can be able to obtain, at runtime, informations about
reifiable types.
J ava Ref lec t ion: r e f l e c t e d t y p e s a r e r e i f i a b l e t y p e s
If we try to reflect a parameterized type, we get the reified information for the
corresponding raw type:
List<Integer> ints = new ArrayList<Integer>();List<String> strs = new ArrayList<String>();assert ints.getClass() == strs.getClass();assert ints.getClass() == ArrayList.class;
J ava Ref lec t ion: r e f l e c t e d t y p e s a r e r e i f i a b l e t y p e s
The getClass() method is treated specially by the compiler.
In general, if expression e has type T, then the expression e.getClass() has type
Class<? extends |T|>, where |T| is the erasure of the type T.
J ava Ref lec t ion: r e f l e c t e d t y p e s a r e r e i f i a b l e t y p e s
An example:
List<Integer> ints = new ArrayList<Integer>();Class<? extends List> k = ints.getClass();assert k == ArrayList.class;
J ava Ref lec t ion: r e f l e c t e d t y p e s a r e r e i f i a b l e t y p e s
Class literals are restricted: it's not syntactically valid to supply a type parameter to
the type in a class literal. So, the following fragment is illegal:
class ClassLiteral { public Class<?> k = List<Integer>.class; } For class tokens, we must supply a raw type; not even
unbounded wildcards may appear. Replacing List<Integer> with List<?> in the preceding code leads to
an error cascade.
J ava Ref lec t ion: r e f l e c t i o n f o r p r i m i t i v e t y p e s
Every type in Java, including primitive types and array types, has a class literal
and a corresponding class token.
J ava Ref lec t ion: r e f l e c t i o n f o r p r i m i t i v e t y p e s
As example, we can consider int.class:The type of this class token cannot be Class<int>, since int is not a reference type, so it is taken to be Class<Integer>.
So, we expect an Integer type return for a call like int.class.newInstance()...
But???...
J ava Ref lec t ion: r e f l e c t i o n f o r p r i m i t i v e t y p e s
But...the previous call raise an exception!!!
J ava Ref lec t ion: r e f l e c t i o n f o r p r i m i t i v e t y p e s
So...
java.lang.reflect.array.newInstance(int.class,size)
we expect an Integer[] return type, but in fact the return type is int[].
J ava Ref lec t ion: a g e n e r i c r e f l e c t i o n l i b r a r y
Unchecked casts can lead to problems, such as violating:
➢Principle of Truth in Advertising (the reified type of an array must be a subtype
of the erasure of its static type)➢
➢Principle of Indecent Exposure(never publicly expose an array where the
components do not have a reifiable type)
J ava Ref lec t ion: a g e n e r i c r e f l e c t i o n l i b r a r y
How to minimize or
avoid these problems?
J ava Ref lec t ion: a g e n e r i c r e f l e c t i o n l i b r a r y
Casts encapsulations with libraries.An example of a wrapper class
GenericReflection:
public static <T> T newInstance(T object)public static <T> Class<? extends T>
getComponentType(T[] a)public static <T> T[] newArray
(Class<? extends T> k, int size)public static <T> T[] newArray(T[] a, int size)
J ava Ref lec t ion: a g e n e r i c r e f l e c t i o n l i b r a r y
Unchecked casts (present in the implementation of the previous methods) are required because the methods in the Java reflection library cannot
return sufficiently accurate types.
For example:The method newInstance in
java.lang.reflect.Array must have the return type Object rather than the return type T[],
because it may return an array of a primitive type.
J ava Ref lec t ion: a g e n e r i c r e f l e c t i o n l i b r a r y
However, the previous unchecked casts are safe: the cast-iron guarantee is
not violated.
For ex.(referring to the previous one, newInstance(T object)):
we use Constructor.newInstance (in java.lang.reflect) yo avoid the problems
with Class.newInstance.
J ava Ref lec t ion: r e f l e c t i o n f o r g e n e r i c s
With Reflection for Generics, Java gives to us class and methods that support
access to generic types.
J ava Ref lec t ion: r e f l e c t i o n f o r g e n e r i c s
With Reflection for Generics, now we can use classes like Field, Constructor and
Method for reflection.
J ava Ref lec t ion: r e f l e c t i o n f o r g e n e r i c s
The reflection library provides a Type interface to describe a generic type. There is one class that implements this interface and four other interfaces that
extend it, corresponding to the five different kinds of types:
➢class Class➢interface ParameterizedType
➢interface TypeVariable➢interface GenericArrayType
➢interface WildcardType
J ava Ref lec t ion: r e f l e c t i o n f o r g e n e r i c s
Methods are available to:
➢ return the superclass
➢return the super-interfaces of a class as types
➢access the generic type of a field, the argument types of a constructor, the
argument and result types of a method.
top related