Java - Foundation - Reflection

Keywords: Java

Reflection mechanism

  1. What is reflection

  2. Function of reflection

  3. Using reflection to call class structure

1. Cognitive reflex

Positive: under normal circumstances, there are classes before there are class objects

Inverse: you can use the object to find the source of the object

Get classes object:

public final Class<?> getClass()

This method inherits from the Object class, so all classes have this method

public static void main(String[] args) {
    Date date = new Date();
    System.out.println(date.getClass());
}
//Output:
//class java.util.Date

2.Class object instantiation

java.lang.Class is a class. This class is the source of reflection. It has three instantiation methods, as follows:

  • Call the getClass() method in the Object class

    public static void main(String[] args) {
    	Date date = new Date();
    	Class <?> cls = date.getClass();
    	System.out.println(cls);
    }
    
  • Use class. Class to get

    public static void main(String[] args) {
    	Class <?> cls = Date.Class;
    	System.out.println(cls);
    }
    
  • Call the method provided by Class

    Instantiate Class object:

    public static Class<?> forName(String className)
    throws ClassNotFoundException

    public static void main(String[] args) {
    	Class <?> cls = Class.forName("java.util.Date");
     System.out.println(cls);
    }
    

    You can import without using import at this time

3. Reflect instanced objects

When you get a Class, use new to instantiate the object. If there is a Class object, you can instantiate the object through reflection

Instantiate object method:

public T newInstance() throws InstantiationException, IllegalAccessException

Example

class Book{
	
	public Book() {
		System.out.println("********************");
	}
	public String toString() {
		return "This is a book";
		
	}
}
public class test {
	public static void main(String[] args) throws Exception {
        //1. General method, new object
		Book b = new Book();
		System.out.println(b);
		
        //2. Reflection object
		Class<?> cls = Class.forName("com.String.Book");
		Object o = cls.newInstance();
        Book book = (Book)o;
		System.out.println(o);//Output b and o are the same
	}
}

4. Reflection call structure

When there are only parameter constructs in the class, exceptions will be generated through reflection calls

Error code example

package com.String;

public class test {
	public static void main(String[] args) throws Exception {

		Class<?> cls = Class.forName("com.t.Book");
		Object o = cls.newInstance();
		System.out.println(o);
	}
}

Book class, located in other packages

package com.t;

public class Book{
	private String title;
	private double price;
	
	public Book(String title , double price) {
		this.title = title ;
		this.price = price;
	}
	public String toString() {
		return "title:"+this.title+",Price:"+this.price;
		
	}
}

Abnormal information

Exception in thread "main" java.lang.InstantiationException: com.t.Book
	at java.lang.Class.newInstance(Unknown Source)
	at com.String.test.main(test.java:11)
Caused by: java.lang.NoSuchMethodException: com.t.Book.<init>()
	at java.lang.Class.getConstructor0(Unknown Source)
	... 2 more

resolvent:

In the Class class, a method to obtain the constructor is provided

  • Get all construction methods:

    public Constructor <?> [] getConstructors()

  • Gets the construction method of a specified parameter:

    public Constructor < T > getConstructor(Class<?>... parameterTypes)

The return value * * Constructor * * of the above two methods is the object of the java.lang.reflect.Constructor class, which provides an instantiated object method that explicitly passes the content of the parameter structure

public T newInstance(Object... initargs)

Solution code example:

package com.String;

import java.lang.reflect.Constructor;

public class test {
	public static void main(String[] args) throws Exception {

		Class<?> cls = Class.forName("com.t.Book");
		Constructor<?> con = cls.getConstructor(String.class,double.class);
		Object o = con.newInstance("java development",79.8);
		System.out.println(o);
	}
}

In the development of simple JAVA classes, at least one parameterless structure is reserved, which is inconvenient for reflection calls

5. Reflection calling method

Ordinary methods in a class can be called only after the class generates an instantiated object.

There are three ways to instantiate objects

  1. new an object
  2. Clone an object
  3. Reflect an object

In the Class class, the operation to obtain the method is provided

  • Gets all the methods in a class

    public Method[] getMethods()
    
  • Gets the method of the specified name

    public Method getMethod(String name, Class<?>... parameterTypes)
    

    Name is the method name

The return value * * Method * * of the above two methods is the object of java.lang.reflect.Method class

  • Call method:

    public Object invoke(Object obj,
                         Object... args)
    

Sample code

Book class, located in other packages

package com.t;

public class Book{
	private String title;

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
}

Call method:

package com.String;
import java.lang.reflect.Method;

public class test {
	public static void main(String[] args) throws Exception {
		String fielName = "title";
		Class<?> cls = Class.forName("com.t.Book");
		Object o = cls.newInstance();
		Method setMet = cls.getMethod("set" +initcap(fielName), String.class);
		Method getMet = cls.getMethod("get" +initcap(fielName));	
		setMet.invoke(o, "java development");
		System.out.println(getMet.invoke(o));	
	}
	
	//title case
	public static String initcap(String str) {
		return str.substring(0, 1).toUpperCase()+str.substring(1);
	}
}

6. Reflection calling member

Class, memory space can only be allocated after the instantiated object of this class is generated

  • Get all members

    public Field[] getDeclaredFields()
    
  • Gets the specified member

    public Field getDeclaredField(String name)
    

The return value Field of the above two methods is the object of the java.lang.reflect.Field class, which provides the following common methods

  • Get attribute content

    public Object get(Object obj)
    
  • Set attribute content

    public void set(Object obj,Object value)
    

Use example:

Book class, located in other packages

package com.t;

public class Book{
	private String title;

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
}

Reflection call:

package com.String;

import java.lang.reflect.Field;

public class test {
	public static void main(String[] args) throws Exception {
		//1. Instantiate class objects
		Class<?> cls = Class.forName("com.t.Book");
		Object o = cls.newInstance();
		//Get members
		Field titleField = cls.getDeclaredField("title");
		//Cannot access private variable without unpacking
		titleField.setAccessible(true);
		//Set member variables
		titleField.set(o, "python");
		System.out.println(titleField.get(o));	
	}
}

Construction methods and common methods can also be unpacked

7. Summary

  1. There is one more way to instantiate an object: reflection
  2. Simple JAVA classes need to use parameterless construction and the reasons for using the set\get method

Posted by bo0 on Tue, 21 Sep 2021 04:45:23 -0700