[Data structure] Reflection, enumeration

?Author: Xiao Hu_Bu Muzhu
Author’s homepage: Xiao Hu_Bumuzzled’s personal homepage
Included column: A brief discussion of data structure
Continue to update articles and follow bloggers to avoid detours. Thank you for your support

Reflection, enumeration

  • 1. Reflection
    • 1.1 Definition
    • 1.2 Reflection related classes
    • 1.3 Reflection example
      • 1.3.1 Three ways to obtain Class objects
    • 1.3 Reflection advantages and disadvantages
  • 2. Enumeration
    • 2.1 Definition
    • 2.2 Use


1. Reflection

1.1 Definition

Java’s reflection mechanism is in the running state. For any class, you can know all the properties and methods of this class; for any object, you can know Since we can get any of its methods and attributes by calling it, we can modify part of the type information; this function of dynamically obtaining information and dynamically calling object methods is called of the Java language Reflection mechanism.

Many objects in Java programs will appear in two types at runtime: Run-time type (RTTI) andCompile-time type, for example, Person p = newStudent(); this code The type of p in compile time is Person and the run time type is Student. Programs need to discover real information about objects and classes at runtime. By using the reflection program, you can determine which classes the object and class belong to.

1.2 Reflection related classes

Class name Purpose
Class class Represents the entity of the class, representing classes and interfaces in running Java applications
Field class Represents the member variables of the class/properties of the class
Method class Represents the method of the class
Constructor class Represents the constructor of the class

Related methods in the Class class:

  1. Commonly used methods to obtain class-related
Method Purpose
getClassLoader() Get the loader of the class
getDeclaredClasses() Returns an array that contains objects of all classes and interface classes in the class (including Private)
forName(String className) Return the object of the class according to the class name
newInstance() Create an instance of a class
getName() Get the full path name of the class
  1. Commonly used methods to obtain attributes related to the class (the return value of the following methods is Field related)
Method Purpose
getField(String name) Get a public attribute object
getFields() Get all public attribute objects
getDeclaredField(String name) Get a certain attribute object
getDeclaredFields() Get all attribute objects
  1. Get the constructor-related methods in the class (the return values of the following methods are Constructor-related)
Method Purpose
getConstructor(Class… parameterTypes ) Get the public constructors in the class that match the parameter type
getConstructors() Get all the public constructors of the class Constructor method
getDeclaredConstructor(Class… parameterTypes) Get the constructor method in the class that matches the parameter type
getDeclaredConstructors() Get all the constructors of this class
  1. Get the methods related to the methods in the class (the return value of the following methods is related to Method)
Method Purpose
getMethod(String name, Class…< ?> parameterTypes) Get a public method of the class
getMethods() Get all the public methods of the class
getDeclaredMethod(String name, Class… parameterTypes) Get a method of this class
getDeclaredMethods() Get all methods of this class

1.3 Reflection Example

1.3.1 Three ways to obtain Class objects

Before reflection, the first step we need to do is to first get the Class object of the class that currently needs reflection, and then achieve the purpose of reflection through the core method of the Class object, that is: in the running state, for any class, We can know all the properties and methods of this class; for any object, we can call any of its methods and properties. Since we can get it, we can modify some type information.

  1. Use Class.forName(“full path name of the class”); static method. Prerequisite: The full path name of the class has been clarified
  2. Use the .class method. Only suitable for Classes that have been explicitly operated on before compilation
  3. Use the getClass() method of the class object

Example: How to use three methods
Create Student class:

class Student{<!-- -->
    //Private attribute name
    private String name = "hu";
    //Public attribute age
    public int age = 18;
    //Constructor without parameters
    public Student(){<!-- -->
        System.out.println("Student()");
    }
    private Student(String name,int age) {<!-- -->
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }
    private void eat(){<!-- -->
        System.out.println("i am eat");
    }
    public void sleep(){<!-- -->
        System.out.println("i am sleep");
    }
    private void function(String str) {<!-- -->
        System.out.println(str);
    }
    @Override
    public String toString() {<!-- -->
        return "Student{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

Three ways of implementation:

public class TestDemo {<!-- -->
    public static void main(String[] args) {<!-- -->
        //1. Get the Class object through getClass
        Student s1 = new Student();
        Class c1 = s1.getClass();

        //2. Get it directly through the class name.class. This method is the most safe and reliable, and the program performance is higher.
        //This shows that any class has an implicit static member variable class
        Class c2 = Student.class;

        //3. Get it through the forName() static method of the Class object, which is the most commonly used.
        //But ClassNotFoundException exception may be thrown
        Class c3 = null;
        try {<!-- -->
        //Note that this is the full path of the class. If there is a package, you need to add the package path.
            c3 = Class.forName("Student");
        } catch (ClassNotFoundException e) {<!-- -->
            e.printStackTrace();
        }
        System.out.println(c1.equals(c2));
        System.out.println(c1.equals(c3));
        System.out.println(c2.equals(c3));
        //A class will only have one Class instance in the JVM, that is, the one we obtained above
        //c1,c2,c3 perform equals comparison and find that they are all true
    }
}

1.3 Reflection advantages and disadvantages

Advantages:

  1. For any class, you can know all the properties and methods of this class; for any object, you can call any of its methods.
  2. Increase program flexibility and scalability, reduce coupling, and improve adaptive capabilities.
    Disadvantages:
  3. There are efficiency issues with using reflection. This will lead to reduced program efficiency.
  4. Reflection technology bypasses source code technology, thus causing maintenance problems. Reflected code is more complex than the corresponding direct code.

2. Enumeration

2.1 Definition

Enumerations were introduced after JDK1.5. The main purpose is to organize a group of constants. Before this, a group of constants was usually expressed in the same way as defining a constant:

public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLACK = 3;

However, there are disadvantages in using constant examples. For example, there may be a number 1, but it may be misunderstood as RED. Now we can directly use enumerations to organize it. In this way, we have types, enumeration types. . Instead of ordinary plastic surgery 1.

public enum TestEnum {<!-- -->
RED,BLACK,GREEN;
}

Advantages: Organize constants for unified management
Scenario: error status code, message type, color division, state machine, etc…

**Essence:** It is a subclass of java.lang.Enum. That is to say, the enumeration class you write yourself, even if it does not explicitly inherit Enum, it inherits this class by default.

2.2 Use

  1. switch statement
public enum TestEnum {<!-- -->
    RED,BLACK,GREEN,WHITE;
    public static void main(String[] args) {<!-- -->
        TestEnum testEnum2 = TestEnum.BLACK;
        switch (testEnum2) {<!-- -->
            case RED:
                System.out.println("red");
                break;
            case BLACK:
                System.out.println("black");
                break;
            case WHITE:
                System.out.println("WHITE");
                break;
            case GREEN:
                System.out.println("black");
                break;
            default:
                break;
        }
    }
}
//Output: black
  1. Common methods
Method name Description
values() Return all members of the enumeration type in the form of an array
ordinal() Get the index position of the enumeration member
valueOf() Convert ordinary string to enumeration instance
compareTo() Compare the order in which two enumeration members are defined

Implementation of the above method:
Example one:

public enum TestEnum {<!-- -->
    RED, BLACK, GREEN, WHITE;
    public static void main(String[] args) {<!-- -->
        TestEnum[] testEnum2 = TestEnum.values();
        for (int i = 0; i < testEnum2.length; i + + ) {<!-- -->
            System.out.println(testEnum2[i] + " " + testEnum2[i].ordinal());
        }
        System.out.println("=========================");
        System.out.println(TestEnum.valueOf("GREEN"));
    }
}

Run results:

Example two:

public enum TestEnum {<!-- -->
RED,BLACK,GREEN,WHITE;
public static void main(String[] args) {<!-- -->
//Get the enumeration instance BLACK
TestEnum testEnum = TestEnum.BLACK;
//Get the enumeration instance RED
TestEnum testEnum21 = TestEnum.RED;
System.out.println(testEnum.compareTo(testEnum21));//1
System.out.println(BLACK.compareTo(RED));//1
System.out.println(RED.compareTo(WHITE));//-3
}
}

An enumeration in Java is actually a class. So when we define an enumeration, we can also define and use the enumeration like this:

public enum TestEnum {<!-- -->
    RED("red",1),BLACK("black",2),WHITE("white",3),GREEN("green",4);
    private String name;
    private int key;
    /**
     * 1. When the enumeration object has parameters, the corresponding constructor needs to be provided
     * 2. The constructor of an enumeration is private by default
     * @param name
     * @param key
     */
    private TestEnum (String name,int key) {<!-- -->
        this.name = name;
        this.key = key;
    }
    public static TestEnum getEnumKey (int key) {<!-- -->
        for (TestEnum t: TestEnum.values()) {<!-- -->
            if(t.key == key) {<!-- -->
                return t;
            }
        }
        return null;
    }
    public static void main(String[] args) {<!-- -->
        System.out.println(getEnumKey(2));//BLACK
    }
}

The constructor of an enumeration is private by default
For any class, even if its construction method is private, we can still get its instance object through reflection. Although the construction method of an enumeration is also private, we cannot obtain an instance of an enumeration class through reflection