“This is the seventh day of my participation in the First Challenge 2022.

preface

Hello everyone, MY name is Kano, a full stack full stick engineer!

I remember asking myself, “Does this matter? What does this thing do? Why not just new objects?” . It was not until LATER when I started working on some tripartite frameworks and participated in the development of some company infrastructure frameworks that I realized that reflection was a great tool for Java framework development.

Today we will review the reflection mechanism in Java. This chapter mainly focuses on the pre-knowledge of reflection. Other reflection related operations will be updated in the “Learn Java Again” column, if you are interested in this column.

Introduction to the

Official description 👉 Visit address: Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions. The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control. Reflection allows Java code to discover information about fields, methods, and constructors of loaded classes and to operate on their underlying counterparts using reflection fields, methods, and constructors within security limits. This API is suitable for applications that need access to the public members of the target object (based on its runtime class) or the members declared by a given class. It also allows the program to suppress the default reflection access control.

Simply put, reflection allows us to programmatically manipulate all the properties and methods of any loaded class/object at runtime. (Don’t worry about the concept, please keep looking down)

The process by which the JVM loads classes

Before we start the reflection body, let’s talk about how the JVM loads classes.

/** * person class *@author : uu
 * @version : v1.0
 * @Date2022/1/24 * /
@Data
public class Person {
    private String name;
}

/ / test class
@Test
public void test(a){
    System.out.println("Before the new");
	Person person = new Person();
	System.out.println(After the "new");
}
Copy the code

When the test is started, configure the following parameters on the VM: -xx :+TraceClassLoading To print class loading logs. After the test is started, the console prints the following data:

.newBefore [the Loaded com uucoding. Advance. The entity. The Person from file:/Users/uu/IdeaProjects/uu-study/uu-java-study/thinking-java/advance-java-example/target/classes/]newAfter...Copy the code

This line prints to load the Person class from the compiled class file. Let’s draw a simple diagram to understand the flow of the above code:

  1. The person. Java file is compiled into a Person.class file.
  2. The program executes to new Person() to open up memory
  3. The classloader loads the Person.class into JVM memory;
  4. Loading the Person.class into the JVM also loads the Person object, as well as the Class object of the Person class, into JVM memory.

I do not know whether the following problems will occur after reading the above process:

  • If there is no new object, will the startup load the class?

  • New object, do not call, start will load the class?

  • Is it true that classes are only loaded once?

Practice answering questions

I do not know the above three questions, but we can effectively use our idea to test them.

Question 1: If there is no new object, will the startup load the class?

  • Validation step

    1. Remove new Person() from test methods
    2. To start the test class, the VM parameter must be set to-XX:+TraceClassLoading
    3. Check to see if the class’s load log contains the Person class
  • The verification code is as follows:

@Test
public void testEmpty(a){
    -xx :+TraceClassLoading
    // Check if the Person class is loaded without a new object
}
Copy the code
  • The verification results

    • There is no Person class in the log, no new object, and startup will not load the class

Question 2: If the object is new and not called, will the class be loaded?

  • Validation step

    1. The introduction ofspring-boot-starter-webRely on
    2. Build the SpringBoot boot entry
    3. Build a test interface and add new Person() to the method body
    4. To start the SpringBoot program, the VM parameter must be set to-XX:+TraceClassLoading
    5. Check to see if the class’s load log contains the Person class
  • The verification code is as follows:

// Introduce dependencies<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<version>2.6.2</version>
</dependency>
Copy the code
/** * Start class *@author : uu
 * @version : v1.0
 * @Date2022/1/24 * /
@SpringBootApplication
public class Application {
    public static void main(String[] args) { SpringApplication.run(Application.class, args); }}/** * validate reflection controller *@author : uu
 * @version : v1.0
 * @Date2022/1/24 * /
@RestController
@RequestMapping("/test")
public class ReflectController {
    /** * Validates the request to load class *@return
     * @throws Exception
     */
    @GetMapping("/lazyNew")
    public void lazyNew(a) throws Exception {
        newPerson(); }}Copy the code
  • The verification results

    • There is no Person class, and if the object is new and not called, the startup will not load the class
  • Continue validation (will the class be loaded if the interface is requested?)

    1. Browser /Postman requests this interface
    2. Check to see if the class’s load log contains the Person class
  • Continue to validate the results

    • The console prints out the request to load the Person class
  • conclusion

    • As you can see from the validation, only the classes used by the system will be called.

Is it true that classes are only loaded once?

Based on the code in question 2, we call the same interface repeatedly, and the Person class will not be loaded again!

conclusion

Only classes that are used by the system are loaded by the JVM, and each Class is loaded only once, generating a Class object that contains all the information about that Class!

Class

In Java, everything is an object. Classes themselves are also objects; any Class is an instance object of the Class Class. The Person Class above is an instance of the Class Class, which is the type of the Person Class!

Through the process of Class loading, we know that a Class will generate a Class object of its predecessor after being loaded. The Class object contains all the information of the Class. Reflection is to read the Class object, reverse obtain the relevant information of the Class, and perform related operations on it.

How to get the Class object

  • Get by class
public void testCreateClass(a) {
    // Get by class
    Class<Person> personClass = Person.class;
    System.out.println(personClass.getName()); // com.uucoding.advance.entity.Person
}
Copy the code
  • Get by object
public void testCreateClass(a) {
    // Get from the object
    Person person = new Person();
    Class<? extends Person> personClass2 = person.getClass();
    System.out.println(personClass2.getName()); // com.uucoding.advance.entity.Person
}
Copy the code
  • Obtained from the classpath
public void testCreateClass(a) throws ClassNotFoundException {
    // From the classpathClass<? > personClass3 = Class.forName("com.uucoding.advance.entity.Person");
    System.out.println(personClass3.getName()); // com.uucoding.advance.entity.Person
}
Copy the code

Note: The specific use of Class is not discussed in this chapter, but will be fully explained in the next chapter!

Why reflection?

Back to the theme, the above long winded along, it seems that reflection is nothing special! How about 🌰, factory mode, which you’re probably familiar with (or see the factory case here for the new gameplay, Lambda refactoring design mode), we start by passing in a key to get an object. So if we add or reduce classes, we need to adjust the factory, but if we use reflection, there is no need to consider the factory changes, just what we have, what we want to use now!

Reflective shortcomings

The following descriptions can be found in the official documentation: 👉 See the [job-hopping of Reflection] section for the Reflection documentation

Reflections are very powerful, but they should not be used arbitrarily, because using them can cause some problems, such as:

  • Performance overhead: Reflection involves dynamic type resolution, so certain Java VIRTUAL machine optimizations cannot be performed, and you should avoid using reflection in performance-sensitive functions
  • Security limitation: Reflection requires runtime permissions that may not exist at run time under security manager. This is an important consideration for code that must run in a restricted security context, such as in an Applet.
  • Internal exposure: Reflection allows code to perform operations that are illegal in non-reflective code, such as accessing private fields and methods, so using reflection can cause unexpected side effects that can cause code dysfunction and potentially break portability. Reflection code breaks abstraction and therefore may change behavior as the platform evolves.

The source code

  • 👉 source can be accessed here

conclusion

  • This chapter mainly expounds some pre-knowledge of reflection, mainly including the loading mechanism of class, the advantages and disadvantages of reflection;
  • The Class Class is the basis for reflection, and any Class is an instance object of Class;
  • The JVM packages the Class name, package, constructors, properties, and methods into the corresponding Class object when loading.
  • Reflection can get property methods of a Class and so on, essentially operating on that Class object.

Related articles

👉 [Learn again series]

The last

  • Thank you for your patience to see the end, if you feel this article is helpful, please give aPraise 👍orFocus on ➕;
  • Due to my limited technology, the article and code may be wrong, I hope you comment pointed out, very grateful 🙏;
  • At the same time, welcome everyone V I (uu2coding) to discuss learning front-end, Java knowledge, volume and progress together.