• What is reflection?
  • What’s the use of reflection?
  • How to use reflection?

What is reflection?

Reflection is widely used in programs that need to check and control the behavior of changes at run time. The concept of reflection is often confused with introspection. Introspection in Wikipedia is defined as:

  • Introspection is the ability of a program to examine the types and properties of objects at runtime
  • Introspection is the ability of a program to examine simultaneously the construction and behavior of an object at runtime. As defined, introspection is a subset of reflection. In addition to checking, reflection can also control changes.

Introspection Example: instanceof determines whether an object belongs to an instanceof a particular class

if(obj instanceof Dog){
   Dog d = (Dog)obj;
   d.bark();
}
Copy the code

The Reflection Example: class.forname () method can return Class Object based on the given Class string, and we can also initialize an object

// with reflection Class<? > c = Class.forName("classpath.and.classname");
Object dog = c.newInstance();
Method m = c.getDeclaredMethod("bark", new Class<? > [0]); m.invoke(dog);Copy the code

In Java, reflection can be understood as enhanced Introspection because you cannot change the construction of an object, but you can change the visibility of the object’s properties and methods

Why do we need reflection?

With reflection, we can do the following:

  • Examine an object at run time
  • At run time, an object is constructed from a class
  • At run time, the properties and methods of an object are checked
  • At run time, any method of an object is called
  • Change the visibility of object constructors, properties, and methods at run time
  • , etc.

Reflection is a common approach to many frameworks:

  • JUnit, for example, uses reflection to find methods with @test annotations, and then uses reflection to call those methods in unit tests
  • In a Web framework, developers put the interfaces and classes they define and implement into a configuration file. Using reflection, they can dynamically initialize these classes and interfaces automatically at runtime. For example, in Spring, configuration files are used like this:
<bean id="someID" class="com.programcreek.Foo">
    <property name="someField" value="someValue" />
</bean>
Copy the code

When Spring reads the bean file, it initializes the Class by calling the class.forname (String) method “com.programcreek.foo” and then using the set method that reflects the correct get to the configured property and sets the corresponding value into it.

Servlet Web also uses this reflection technique:

<servlet>
    <servlet-name>someServlet</servlet-name>
    <servlet-class>com.programcreek.WhyReflectionServlet</servlet-class>
<servlet>
Copy the code

How to use reflection

For details on how to use reflection, please refer to the Java API below

Get the class name from the object:

package myreflection;
import java.lang.reflect.Method;
 
public class ReflectionHelloWorld {
	public static void main(String[] args){
		Foo f = new Foo();
		System.out.println(f.getClass().getName());			
	}
}
 
class Foo {
	public void print() {
		System.out.println("abc"); }}Copy the code

Output:

myreflection.Foo
Copy the code

Calls a method of a location object

package myreflection;
import java.lang.reflect.Method;
 
public class ReflectionHelloWorld {
	public static void main(String[] args){
		Foo f = new Foo();
 
		Method method;
		try {
			method = f.getClass().getMethod("print", new Class<? > [0]); method.invoke(f); } catch (Exception e) { e.printStackTrace(); } } } class Foo { public voidprint() {
		System.out.println("abc"); }}Copy the code

output:

abc
Copy the code

Create an object from a class

package myreflection;
 
public class ReflectionHelloWorld {
	public static void main(String[] args){
		//create instance of "Class"Class<? > c = null; try{ c=Class.forName("myreflection.Foo");
		}catch(Exception e){
			e.printStackTrace();
		}
 
		//create instance of "Foo"
		Foo f = null;
 
		try {
			f = (Foo) c.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}	
 
		f.print();
	}
}
 
class Foo {
	public void print() {
		System.out.println("abc"); }}Copy the code

Get the constructor and create the instance

package myreflection;
 
import java.lang.reflect.Constructor;
 
public class ReflectionHelloWorld {
	public static void main(String[] args){
		//create instance of "Class"Class<? > c = null; try{ c=Class.forName("myreflection.Foo");
		}catch(Exception e){
			e.printStackTrace();
		}
 
		//create instance of "Foo"Foo f1 = null; Foo f2 = null; //get all constructors Constructor<? > cons[] = c.getConstructors(); try { f1 = (Foo) cons[0].newInstance(); f2 = (Foo) cons[1].newInstance("abc");
		} catch (Exception e) {
			e.printStackTrace();
		}	
 
		f1.print();
		f2.print();
	}
}
 
class Foo {
	String s; 
 
	public Foo(){}
 
	public Foo(String s){
		this.s=s;
	}
 
	public void print() { System.out.println(s); }}Copy the code

output:

null
abc
Copy the code

Similarly, if you can get the constructor, you can use Class Instance to get the interface that the Class implements, its superclass, its properties, and so on

Use reflection to change the size of an array

package myreflection;
 
import java.lang.reflect.Array;
 
public class ReflectionHelloWorld {
	public static void main(String[] args) {
		int[] intArray = { 1, 2, 3, 4, 5 };
		int[] newIntArray = (int[]) changeArraySize(intArray, 10);
		print(newIntArray);
 
		String[] atr = { "a"."b"."c"."d"."e" };
		String[] str1 = (String[]) changeArraySize(atr, 10);
		print(str1); } // change array size public static Object changeArraySize(Object obj, int len) { Class<? > arr = obj.getClass().getComponentType(); Object newArray = Array.newInstance(arr, len); //do array copy
		int co = Array.getLength(obj);
		System.arraycopy(obj, 0, newArray, 0, co);
		returnnewArray; } / /print
	public static void print(Object obj) { Class<? > c = obj.getClass();if(! c.isArray()) {return;
		}
 
		System.out.println("\nArray length: " + Array.getLength(obj));
 
		for (int i = 0; i < Array.getLength(obj); i++) {
			System.out.print(Array.get(obj, i) + ""); }}}Copy the code

output:

Array length: 10
1 2 3 4 5 0 0 0 0 0 
Array length: 10
a b c d e null null null null null 
Copy the code

conclusion

We briefly introduced what is reflection, reflection can be used for what, how to use reflection and other issues, can have a general understanding of reflection, specific concept details also need to refer to more information