Contents | Prev | Next

Overview

The JavaTM Core Reflection API provides a small, type-safe and secure API which supports introspection about the classes and objects in the current Java Virtual Machine. If permitted by security policy, the API can be used to construct new class instances and new arrays, to access and modify fields of objects and classes, to invoke methods on objects and classes, and to access and modify elements of arrays.

The reflection API consists of:

There are also some additions to the java.lang package to support reflection:

The reflection API accomodates two categories of applications:

Reflection Model

The Field, Method, and Constructor classes are final, and are only created by the Java Virtual Machine. Objects which are instances of these classes are used to manipulate the underlying objects, getting and setting field values, invoking methods on objects or classes, and creating new instances of classes. The final uninstantiable class Array provides static methods that permit creating new arrays, and getting and setting the elements of arrays.

The classes Field, Method and Constructor implement the Member interface. The methods of Member are used to query a reflected member for basic identifying information. This consists of the class or interface declaring the member, the name of the member, and the Java language modifiers (such as public, protected, abstract, synchronized, etc.) for the member.

A Field object represents a reflected field. The underlying field may be a class variable (static field) or an instance variable (non-static field). Methods of class Field can be used to obtain the type of the underlying field, and to get and set the underlying field's value on objects.

A Method object represents a reflected method. The underlying method may be an abstract method, an instance method, or a class (static) method. Methods of class Method can be used to obtain the formal parameter types, the return type, and the checked exception types of the underlying method. The invoke method of class Method can be used to invoke the underlying method on objects. Instance and abstract method invocation uses dynamic method resolution based on the target object's run-time class and the reflected method's declaring class, name, and formal parameter types. (Thus, it is permissible to invoke a reflected interface method on an object that is an instance of a class that implements the interface.) Static method invocation uses the underlying static method of the method's declaring class.

A Constructor object represents a reflected constructor. Methods of class Constructor can be used to obtain the formal parameter types and the checked exception types of the underlying constructor. The newInstance method of class Constructor can be used to create and initialize a new instance of the class that declares the constructor, provided the class is instantiable.

The Array class is an uninstantiable class that exports class methods to create Java arrays with primitive or class component types, and to get and set array component values.

The Modifier class is an uninstantiable class that exports class methods to decode Java language modifiers for classes and members, which are encoded in an integer.

Finally, there are nine new Class objects (not classes) that are used to represent the eight primitive Java types and void at run-time. These objects are used by the reflection API to represent primitive field types, primitive method and constructor parameter types, and primitive method return types. These Class objects are created by the Java Virtual Machine, and have the same names as the types that they represent. The Class objects may only be referenced via the following public final static variables:


    java.lang.Boolean.TYPE
    java.lang.Character.TYPE
    java.lang.Byte.TYPE
    java.lang.Short.TYPE
    java.lang.Integer.TYPE
    java.lang.Long.TYPE
    java.lang.Float.TYPE
    java.lang.Double.TYPE
    java.lang.Void.TYPE

Security Model

Access to the reflection API is controlled on a class-by-class basis by the system's security manager. There are two levels of checks to enforce security and safety, as follows:

The initial policy decision is centralized in a new method of class SecurityManager:


    void checkMemberAccess(Class,int) throws SecurityException	

where the Class parameter identifies the class or interface whose members need to be accessed and the int parameter identifies the set of members to be accessed-either Member.PUBLIC or Member.DECLARED.

If the requested access to the specified set of members of the specified class is denied, the method should throw a SecurityException. If the requested access to the set is granted, standard Java language access control will be enforced when using a reflected member from this set. This is when a Field is used to get or set a field value, when a Method is used to invoke a method, or when a Constructor used to create and initialize a new instance of a class. If access is denied at that point, the reflected member will throw an IllegalAccessException.

Java Language Policy

The Java language security policy for applications is that any code may gain reflective access to all the members and constructors (including non-public members and constructors) of any class it may link against. Application code that gains reflective access to a member or constructor may only use the reflected member or constructor with standard Java language access control.

JDK 1.1 Security Policy

In Sun's JDK 1.1 (but not part of the language specification itself), class AppletSecurity implements the following policy:

Any code that gains reflective access to a member may only use it with standard Java language access control. There is no notion of privileged code, and no means to override the standard language access control checks.

This policy is conservative with respect to untrusted code-it is more restrictive than the Java Virtual Machine's linker. For example, an untrusted class cannot, by itself, access a protected member of a system superclass via reflection, although it can via the linker. (However, system code may access such members and pass them to untrusted code.)

The JDK security policy is expected to evolve with Java's security framework.

Data Conversions

Certain methods in the reflection package perform automatic data conversions between values of primitive types and objects of class types. These are the generic methods for getting and setting field and array component values, and the methods for method and constructor invocation. Wrapping conversions are used to convert from values of primitive types to objects of class types. Unwrapping conversions are used to convert objects of class types to values of primitive types. The rules for these are defined below.

Additionally, field access and method invocation permit widening conversions on primitive and reference types. These conversions are documented in The Java Language Specification, section 5, and are detailed below.

Wrapping and Unwrapping Conversions

A primitive value is automatically wrapped in an object when it is retrieved via Field.get or Array.get, as is a primitive value returned by a method invoked via Method.invoke.

Similarly, an object value is automatically unwrapped when supplied as a parameter in a context that requires a value of a primitive type. The contexts are

The following table shows the correspondences between primitive types and class (wrapper) types:
boolean java.lang.Boolean
char java.lang.Character
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double

A method that returns void returns the special reference null when invoked via Method.invoke.

Widening Conversions

The widening conversions permitted at run-time by the reflection package are those permitted at compile time in method invocation contexts as defined in The Java Language Specification, section 5.3.

Widening conversions are performed in the following situations.

The permitted widening primitive conversions1 are:

The permitted widening reference conversions2 are:

Packaging

The reflection API is in a new subpackage of java.lang named java.lang.reflect. This avoids compatibility problems caused by Java's default package importation rules.



Contents | Prev | Next
1 See The Java Language Specification, section 5.1.2.

2 See The Java Language Specification, section 5.1.4.

reflection-comments@worthy.eng.sun.com
Copyright © 1996 Sun Microsystems, Inc. All rights reserved.