Java reflection

The official documentation

Docs.oracle.com/javase/tuto…

The role of Java

Reflection is typically used by programs that need to be able to examine or modify the runtime behavior of an application running in a Java virtual machine, a relatively advanced feature that can only be used by developers with a basic knowledge of the language. With this in mind, reflection is a powerful technique that enables applications to do things that would otherwise be impossible.

1. Scalability

Applications can use external user-defined classes by creating instances of extensibility objects with fully qualified names.

Class browser and visual development environment

The class browser needs to be able to enumerate the members of a class. Visual development environments can benefit from leveraging the type information available in reflection to help developers write correct code.

Debuggers and test tools

The debugger needs to be able to examine private members on the class. Reflection can be used by test tools to systematically invoke discoverable SET apis defined on classes to ensure high-level code coverage in the test suite.

Disadvantages of reflection

Reflection is powerful, but should not be used arbitrarily. If you can perform an operation without reflection, it is preferable to avoid it. Keep the following questions in mind when accessing code through reflection.

1. Performance overhead

Because reflection involves dynamically resolved types, some Java virtual machine optimizations cannot be performed. Therefore, reflective operations perform worse than non-reflective operations, and should be avoided in frequently invoked code segments in performance-sensitive applications.

2. Safety restrictions

Reflection requires runtime permissions that may not exist at runtime under security Manager. This is an important consideration for code that must run in a restricted security context, such as in applets.

3. Internal contact

Because reflection allows code to perform operations that are illegal in non-reflective code, such as accessing private fields and methods, using reflection can cause unintended side effects that can lead to code dysfunction and potentially break portability. Reflection code breaks abstraction, so it is possible to change behavior by upgrading the platform.

Reflection like method

Get the Class object

Object.getClass()

.class grammar

Primitive types cannot getClass objects using the object.getclass () method

Class.forName()

You can use this method to get the Class object if you can get the full name of the Class

The wrapper class TYPE static variable for the primitive TYPE

Other methods that return Class objects

  1. Class.getSuperclass()
  2. Class.getclasses () returns all public classes, interfaces, and enumerations that are members of the Class, including inherited members.
  3. Class.getdeclaredclasses () returns all Class interfaces and enumerations explicitly declared in this Class.
  4. Class.getdeclaringclass () returns classes declared in such member variables. The anonymous Class does not have DeclaringClass, but has EnclosingClass
  5. java.lang.reflect.Field.getDeclaringClass()
  6. java.lang.reflect.Method.getDeclaringClass()
  7. java.lang.reflect.Constructor.getDeclaringClass()
  8. Class.getenclosingclass () returns the immediate enclosing Class of the Class.

Check class modifiers and types

You can declare a Class with one or more modifiers that affect its runtime behavior:

  1. public, protected, and private
  2. abstract
  3. static
  4. final
  5. strictfp
  6. Annotations

Gets a member of the class

Get member variables

Class API List return value? Inherited member? Private member?
getDeclaredField() no no yes
getField() no yes no
getDeclaredFields() yes no yes
getFields() yes yes no

Get member method

Class API List return value? Inheritance method? Private methods?
getDeclaredMethod() no no yes
getMethod() no yes no
getDeclaredMethods() yes no yes
getMethods() yes yes no

A constructor

Class API List return value? Inheritance method? Private methods?
getDeclaredConstructor() no N/A1 yes
getConstructor() no N/A1 no
getDeclaredConstructors() yes N/A1 yes
getConstructors() yes N/A1 no

troubleshooting

  1. Error: Compiler Warning: “Note:… uses unchecked or unsafe operations”
  2. InstantiationException when the constructor is not accessible

Members of the

Fields

Get field type

  • Field.gettype () : Gets the type of the Field
  • Fiel.getgenerictype () : Gets the generic type of the Field

Retrieves and resolves field modifiers

  • Field.getmodifiers () : Gets Field modifiers
  • Field.issynthetic () : determines whether a Field isSynthetic
  • Field.isenumconstant () : checks whether the Field is enumeration

Gets and sets field values

  • Field.set*() : Gets the Field value
  • Field.get*() : Sets the Field value

troubleshooting

  1. IllegalArgumentException due to Inconvertible Types
  2. NoSuchFieldException for Non-Public Fields
  3. IllegalAccessException when Modifying Final Fields

Methods

Gets method type information

  • Method.toGenericString()
  • Method.getReturnType()
  • Method.getGenericReturnType()
  • Method.getParameterTypes()
  • Method.getGenericParameterTypes()
  • Method.getExceptionTypes()
  • Method.getGenericExceptionTypes()

Gets the name of the method parameter

  • Method.getparameters () : Gets Method parameters
  • Parameter.gettype () : Gets the Parameter type
  • Parameter.getname () : Gets the Parameter name
  • Parameter.modifiers () : Gets Parameter Modifiers
  • Parameter.isimplicit () : true if this Parameter is declared implicitly in the source code
  • Parameter.isnamepresent () : true if the Parameter has a name according to the.class file
  • Parameter.issynthetic () : true if this Parameter is neither implicitly nor explicitly declared in the source code

Retrieves and resolves method modifiers

  • Method.getmodifiers () : Gets Method modifiers
  • Method.issynthetic () : Returns true whether the executable is a synthetic construct
  • Method.isvarargs () : Returns true if the executable is declared to take a variable number of arguments
  • Method.isbridge () : true if the Method is a bridge Method

A method is called

  • Method.invoke() : Invoke a Method

troubleshooting

  1. NoSuchMethodException Due to Type Erasure
  2. IllegalAccessException when Invoking a Method
  3. IllegalArgumentException from Method.invoke()
  4. InvocationTargetException when Invoked Method Fails

Constructors

Get constructor

Retrieves and resolves constructor modifiers

  • Constructor.getModifiers()

Create a new instance

  • Constructive.newinstance () : preferred use
  • Class.newInstance()

troubleshooting

  1. InstantiationException Due to Missing Zero-Argument Constructor
  2. Class.newInstance() Throws Unexpected Exception
  3. Problems Locating or Invoking the Correct Constructor
  4. IllegalAccessException When Attempting to Invoke an Inaccessible Constructor

Array and enumeration types

An array of

Identifying array types

  • Class.isArray()

Creating a new array

  • Array.newInstance()

Gets and sets the array and its components

  • Array.set*()
  • Array.get()

troubleshooting

  1. IllegalArgumentException due to Inconvertible Types
  2. ArrayIndexOutOfBoundsException for Empty Arrays
  3. IllegalArgumentException if Narrowing is Attempted

The enumeration

Identifying enumeration types

  • Class.isenum () : Enumerations cannot be instantiated by reflection; enumeration constants are unique
  • Class.getEnumConstants()
  • Field.isEnumConstant()

Use enumeration types to get and set fields

  • Field.set()
  • Field.get()

troubleshooting

  1. IllegalArgumentException When Attempting to Instantiate an Enum Type
  2. IllegalArgumentException when Setting a Field with an Incompatible Enum Type