top of page
Search

Java Reflection

Updated: Jul 29

Using Java Reflection you can inspect or/and modify runtime attributes of classes, interfaces, fields, and methods at runtime. This is done via the Java class java.lang.reflect.Constructor. Additionally, we can instantiate new objects, invoke methods and get or set field values using reflection.


Intro


When it comes to this "reflection" term, you might wonder which cases the reflection is used in? Typically, reflection is not a prevalent technique for some newbies but highly-recommended by experienced developers.

For example, you have an object (but you don't know the type) and you want to call method doSomething() of that object. This is feasible with java reflection:

This article will focus on the basics of reflection and how to use tons of great features provided by Java reflection.


Java Class Object


When using Java reflection the starting point is often a Class object representing some Java class you want to inspect via reflection. For instance, to obtain the Class object for a class named MyObject at compile time you could write:

If you don't know the name at compile-time but have the class name as a string at runtime, you can do this:

When using the Class.forName() method you must supply the fully qualified class name. That is the class name including all package names. For instance, if MyObject is located in package com.tuyen.myapp then the fully qualified class name is com.tuyen.myapp.MyObject.


From Class we can retrieve info of:

  • Class Name

  • Class Modifiers (public, private, synchronized, etc..)

  • Package Info

  • Superclass

  • Implemented Interfaces

  • Constructors

  • Methods

  • Fields

  • Annotations

 

Class Name


From a Class object, you can obtain its name in two versions.

getName(): the fully qualified class name (including package name).

getSimpleName(): class name without the package name.

 

Modifiers


The class modifiers can be "public", "private", "static", "abstract", etc...You can obtain the class modifiers like this:

The modifiers are packed into an int, and you can check modifiers using these methods which return a boolean result (true or false).

Some available methods: isInterface(), isNative(), isPrivate(), isProtected(), isPublic(), isStatic(), isStrict(), isSynchronized(), isTransient(), isVolatile().

 

Package Info


Obtain information about package from a Class object:

From the Package, you have access to information about the package like its name.

 

Superclass


From the Class object, you can access the superclass of the class. Here is how:

The superclass class object is also a Class object like any other, so you can continue doing class reflection on that too.

 

Implemented Interfaces


It is possible to get a list of the interfaces implemented by a given class. Here is how:

A class can implement many interfaces. Therefore an array of Class is returned. Interfaces are also represented by Class objects in Java Reflection.


NOTE: Only the interfaces specifically declared implemented by a given class is returned. If a superclass of the class implements an interface, but the class doesn't specifically state that it also implements that interface, that interface will not be returned in the array.

 

Constructors


You can obtain constructor:

The Constructor[] array will have one Constructor instance for each public constructor declared in the class.

If you know the precise parameter types of the constructor you want to access, you can do so rather than obtain the array of all constructors. This example returns the public constructor of the given class which takes a String and Integer as parameters:

You can read what parameters a given constructor takes:

From constructors, you can create a new instance of class object:

The Constructor.newInstance() method takes an optional amount of parameters, but you must supply exactly one parameter per argument in the constructor you are invoking. In this case, it was a constructor taking an Integer, so one Integer must be supplied.

 

Methods


Obtain Method from a Class object:

If you know precise parameter types of the method you want to access, you can do so rather than obtain all methods in the array. Below example returns the public method named doSomething(), which takes a String and an Integer as parameters:

If the method you are trying to access takes no parameters, just pass null, like this:

You can read what parameters a given method takes or return type of method:

You can invoke a method like this:

The null parameter is the object you want to invoke the method on. If the method is static, you supply null instead of an object instance. In this example, if doSomething(String.class) is not static, you need to supply a valid MyObject instance instead of null.

 

Fields


The Field class is obtained by:

Get and Set field values:

Once you have obtained a Field reference you can get and set its values using the Field.get() and Field.set() methods, like this:

The objectInstance parameter passed to the get and set method should be an instance of the class that owns the field. In the above example, an instance of MyObject is used, because the someField is an instance member of the MyObject class.

If the field is a static field (public static ...) pass null as a parameter to the get and set methods, instead of the objectInstance parameter passed above.


Through reflection, we can access the private variables and methods of a class with the help of its class object and invoke the method by using the object as discussed above. We use two methods below for this purpose.

  • Class.getDeclaredField(FieldName): Used to get the private field. Returns an object of type Field for the specified field name.

  • Field.setAccessible(true): Allows accessing the field irrespective of the access modifier used with the field.

 

Advantages of using Reflection:

  1. Extensibility Features: An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.

  2. Debugging and testing tools: Debuggers use the property of reflection to examine private members in classes.

Drawbacks:

  1. Performance Overhead: Reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

  2. Exposure of Internals: Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

92 views0 comments

ความคิดเห็น


bottom of page