CSC/ECE 517 Fall 2009/wiki2 5 jdf
Reflection APIs
Introduction
Reflection is a feature offered by many modern programming languages and its use is particularly prevalent in object oriented languages, such as Java and Ruby. Reflection provides programmers with the ability to write code that determines information about a set of code during run time. The information that is acquired through reflection can be used to develop very sophisticated program features. Programs can be written to adapt based on the characteristics of the code itself. The information that can be obtained via reflection includes elements such as:
- The class types of objects that are present in the running program
- The class hierarchy of an object or set of objects
- The attributes and methods of objects
- Details of the method calls supported by objects [1]
The objective of this article is to provide an overview of the different Application Programming Interfaces or APIs that exist in various Object Oriented Languages to provide reflection functionality.
Languages that Provide a Reflection API
Among the languages that provide Reflection APIs we count the following:
Reflection in Ruby
Reflection is built into Ruby, it is a standard feature of the language. Objects in Ruby support reflection by default, hence it is not necessary to use any external or additional libraries. In essence, the programmer does not need to do anything special to start using reflection, it is a native part of the language [1, 2]. Additionally, Ruby's intuitive syntax and ease of use make it possible for someone who is not an expert to write Ruby code that uses reflection.
Ruby's reflection functionality is made available by the Object class from which everything in Ruby is derived. The API includes methods to retrieve an object's type, the list of methods it supports, and its attributes. It is also possible to dynamically invoke methods. The following table describes the basic API.
Method | Description |
---|---|
class | Returns the type of an object. |
methods | Returns the list of methods supported by an object. |
class_variables | Returns the list of class-level variables supported by an object. |
instance_variables | Returns the instance-level variables supported by an object. |
send | Dynamically calls a method supported by an object. |
The following Ruby code will display the class type of a variable:
mystr = "Hello World!" mystr.class
The following code displays all the methods that are exposed by the class:
mystr.methods
Reflection in Java
Reflection in Java is achieved by making method calls on a Class object [3]. Before using reflection on an object, first it is necessary to map it to an instance of Class. It is important to note that this method only works for types that are derived from Object, not all types in Java are an object, e.g. boolean.
The following table describes the basic API.
Method | Description |
---|---|
getClass() | Returns an object of the type Class, which can be used to discover more information about another object. |
getName() | Returns the type of an object. |
getMethods() | Returns the list of methods supported by an object. |
The following code shows how to obtain the Class from a string object:
Class myclass = "Hello World!".getClass();
We can use the myclass object to retrieve the name of the class, in this case String:
myclass.getName();
To map a non-object Java type, such as the primitive type boolean to a Class, the following syntax must be used:
boolean recordExists; Class myclass = recordExists.class;
To retrieve the set of methods that are supported by a given class, the following syntax is used:
myclass.getMethods();
Reflection in C#
Using reflection in C# requires the use of the System.Reflection assembly which is specifically dedicated to such purpose [4, 5]. Assemblies in C# are akin to packages in Java. The use of reflection in C# is an advanced feature, intended mainly for expert developers. Additionally, the performance of C# code that relies on reflection is considerably slower than standard code.
The following table describes the basic API.
Method | Description |
---|---|
GetType() | Returns an instance of System.Type which can be used to invoke reflection methods on an object. |
GetMethods() | Returns the list of methods supported by the an object. |
GetFields() | Returns the set of attributes that are supported by the an object. |
InvokeMember() | Uses reflection to call a method supported by an object. |
The following code fragment illustrates how to obtain and display the type of a class using C#:
String myclass = "Hello World!"; System.Type classType = myclass.GetType(); System.Console.WriteLine(classType);
Reflection in VB.NET
VB.NET is a Microsoft programming language which is also based on the .NET Framework and hence its reflection features are similar to those of C#. The main difference between using reflection in VB.NET and using it in C# is the syntax of the language itself.
The following code illustrates the use of reflection in VB.NET:
Dim myclass As String = "Hello World!" Dim classType As System.Type = myclass.GetType() System.Console.WriteLine(classType)
Reflection in Smalltalk-80
Smalltalk-80 offers powerful reflection capabilities. In Smalltalk everything is an object, and objects support reflection natively. Features of the language also include the ability to explore the contents of the run-time stack and redefining methods at run-time[7].
Reflection in Smalltalk-80 is based on the fact that programs are compiled into byte code that is interpreted by a virtual machine. The virtual machine provides the necessary functionality for reflection in the message-passing mechanism.
Ease of Use
The level of implementation and ease of use varies among languages. Usually reflection is a feature reserved for expert programmers, mainly due to the complexity of the syntax needed and also to the additional libraries, packages, or assemblies that must be utilized for reflection to work. It is important to note that in Languages such as C# and Java it is not possible to use reflection directly. In Java all calls must be done through a Class object and in C# (also VB.NET) all calls are made through a Type object. The two methods are similar but C# seems to have the most straight forward API.
Judging from the Ruby examples where simple and intuitive syntax is evidenced, coupled with the fact that intermediate objects are not necessary, it may be concluded that reflection is much easier to use in languages where it is a native part of the language syntax, e.g. Ruby.
Other Considerations
Reflection is a very powerful programming feature, usually reserved for more experienced programmers. Nevertheless, the use of reflection must be done keeping in mind that the advantages achieved from discovering details about the code during run time usually come at a price[3]. The following must be considered:
- Reflection incurs heavy overhead, i.e. code that uses reflection cannot be optimized by the compiler in the same way that standard code is. Code that relies on reflection should be expected to run slower.
- Reflection may not work in the deployed environment due to security constraints.
- Code that uses reflection may result in undesired or unexpected side effects, for instance changes to private variables that were never intended to be exposed.
Resources
References
[1] D. Thomas, C. Fowler and A. Hunt, Programming Ruby, The Pragmatic Programmer's Guide. 2nd Edition. The Pragmatic Bookshelf.
[2] Help and documentation for the Ruby programming language, RUBY-DOC.ORG
[3] Trail: The Reflection API, The Java Tutorials, Sun Microsystems, http://java.sun.com/docs/books/tutorial/reflect/
[4] Viewing Type Information, .NET Framework Developer's Guide, http://msdn.microsoft.com/en-us/library/t0cs7xez%28VS.80%29.aspx
[5] Reflection, C# Programming Guide, http://msdn.microsoft.com/en-us/library/ms173183%28VS.80%29.aspx
[6] Reflection (C# and Visual Basic), http://msdn.microsoft.com/en-us/library/ms173183%28VS.100%29.aspx
[7] Foote B. and Johnson R.E., Reflective Facilities in Smalltalk-80, University of Illinois at Urbana-Champaign, Dept. of Computer Science, 1989, http://www.laputan.org/ref89/ref89.html
CSC 517 Fall 2009
Wiki 2 Assignment
Author: Newwolf