I've been working for some time. I think it's time to review some basic knowledge of Java, so I wrote this article. In the ordinary development process, the front end writes more, and the back end can't forget!
1, Case departure
Prepare a template class first:
public class User { public int id; private String name; public User(String name, int id) { this.id = id; this.name = name; } private User(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
2. Start reflection
import java.lang.reflect.*; public class Test { public static final String LINE = "\n"; public static final String SPACE = " "; public static void main(String[] args) throws Exception { Class<?> c = Class.forName("com.User"); // Class<?> c = Test.class.getClassLoader().loadClass("com.User"); StringBuilder sb = new StringBuilder(); // Print package, class name String packageName = c.getPackage().getName(); sb.append("package " + packageName + ";" + LINE); sb.append(LINE); sb.append("public class " + c.getSimpleName() + "{" + LINE); // Print member variables Field[] declaredFields = c.getDeclaredFields(); for (Field field : declaredFields) { // Field.getModifiers() returns a numeric value of type int, which is used to identify public, static and other identifiers String fieldModifier = Modifier.toString(field.getModifiers()); // Gets the brief name of the property type String typeName = field.getType().getSimpleName(); // The name of the property String fieldName = field.getName(); sb.append(SPACE + fieldModifier + " " + typeName + " " + fieldName + ";" + LINE); } sb.append(LINE); // Print structure Constructor<?>[] declaredConstructors = c.getDeclaredConstructors(); for (Constructor<?> constructor : declaredConstructors) { // Identifier of the constructor String constructorModifier = Modifier.toString(constructor.getModifiers()); sb.append(SPACE + constructorModifier + " " + c.getSimpleName() + " " + "("); // Print constructor parameters printParam(sb, constructor.getParameterTypes()); } // Printing method Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { // Identifier of the method String methodModifier = Modifier.toString(method.getModifiers()); // Method return type String returnTypeName = method.getReturnType().getSimpleName(); // Method name String methodName = method.getName(); sb.append(SPACE + methodModifier + " " + returnTypeName + " " + methodName + "("); printParam(sb, method.getParameterTypes()); } sb.append("}"); System.out.println(sb.toString()); } private static void printParam(StringBuilder sb, Class<?>[] parameterTypes2) { Class<?>[] parameterTypes = parameterTypes2; for (int i = 0; i < parameterTypes.length; i++) { // Type of parameter String simpleName = parameterTypes[i].getSimpleName(); if (i == 0) { sb.append(simpleName + " args"); } else { sb.append(", " + simpleName + " args"); } } sb.append(") {" + LINE); sb.append(SPACE + "}" + LINE); sb.append(LINE); } }
The final results are as follows:
2, Analysis of reflection method
2.1 reflection mode
In the code, we can find that there are two basic reflections:
- Class.forName()
- getClassLoader().loadClass()
First, add static block code in the template class:
Let's run the code of two reflection modes:
forName:
getClassLoader:
The conclusions are as follows:
Initialization: objects reflected through forName will be initialized (static code will be executed), while objects reflected through getClassLoader will not be initialized.
2.2 printing of modifiers
If we want to print the modifiers of methods and properties, we should get them through the Modifier class. Look at this line of code:
String fieldModifier = Modifier.toString(field.getModifiers());
Take a look at the source code of Modifier.toString:
public static String toString(int mod) { StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0) sb.append("public "); if ((mod & PROTECTED) != 0) sb.append("protected "); if ((mod & PRIVATE) != 0) sb.append("private "); /* Canonical order */ if ((mod & ABSTRACT) != 0) sb.append("abstract "); if ((mod & STATIC) != 0) sb.append("static "); if ((mod & FINAL) != 0) sb.append("final "); if ((mod & TRANSIENT) != 0) sb.append("transient "); if ((mod & VOLATILE) != 0) sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & NATIVE) != 0) sb.append("native "); if ((mod & STRICT) != 0) sb.append("strictfp "); if ((mod & INTERFACE) != 0) sb.append("interface "); if ((len = sb.length()) > 0) /* trim trailing space */ return sb.toString().substring(0, len-1); return ""; }
Obviously, it is mapped and returned by the type of language modifier (int type).
There are three places in the case code that support obtaining modifier types:
- field.getModifiers(): field modifiers.
- constructor.getModifiers(): construct modifiers.
- method.getModifiers(): modifier of the method.
2.3 difference between getdeclaredxxx and getxxx
Take Field as an example:
Field[] declaredFields = c.getDeclaredFields(); Field[] fields = c.getFields();
The cases are as follows:
1. Create a new Parent class:
public class Parent { public String parentAddress; private Integer Number; }
2. Let the User class inherit the Parent class
3. Test 1: getdeclaraedfields print member variables:
4. Test 2: getFields print member variables:
The differences are as follows:
Comparison content | getDeclaredFields | getFields |
---|---|---|
The scope of the class being acted on | Current class only | You can also include parent classes |
Modifier range of action | You can get public and non-public types | Only relevant values of public type can be obtained |
2.4 what is the difference between getsimplename and getName
Take this line of code as an example:
String typeName = field.getType().getSimpleName();
If I change getSimpleName to getName, see how the output will be different:
It can be found that gatName outputs the full name of the type, and the corresponding getSimpleName returns the type name as the name suggests.
For other related attributes and API s, the code comments are written in detail, so I won't expand the introduction.