1, Reflection mechanism
1. Overview of reflection mechanism
1.1 reflection mechanism
1.2 package of reflection mechanism related classes
Reflection mechanism in Java lang.Class.* Bao Xia
1.3 important classes related to reflection mechanism
1.4 three ways to obtain Class
package reflex; import java.util.Date; /** * To operate the bytecode of a class, you first need to obtain the bytecode of the class. How to obtain Java long. Class instance? * Three ways * 1,Class c=Class.forName("Full class name with package name ") * 2,Class c =Object getClass(); * 3, */ public class ReflectTest01 { public static void main(String[] args) { /*The first way: through a static method Class.forName() 1,Static method 2,The argument to the method is a string 3,String requires a full class name 4,The full class name must contain the package name. java.lang package cannot be omitted */ Class c1=null; Class c2=null; try { c1=Class.forName("java.lang.String");//c1 stands for String Class file, or String type c2=Class.forName("java.util.Date");//c2 stands for Date type Class c3=Class.forName("java.lang.Integer");//c3 stands for Integer type Class c4=Class.forName("java.lang.System");//c4 stands for System type } catch (ClassNotFoundException e) { e.printStackTrace(); } //The second method //Every object in java has a method: getClass() String s="abc"; Class x=s.getClass();//x stands for String Class bytecode file, x represents String type System.out.println(c1==x); Date time=new Date(); Class y=time.getClass(); System.out.println(c2==y);//Ture (the memory addresses saved in C2 and y variables are the same, both pointing to the bytecode in the method area) //The third way: any type in the java language, including basic data types, he has class attribute Class z=String.class; Class k=int.class; System.out.println(k==z);//false, z for String type, k for int type } }
1.5 instantiating objects by reflection
package reflect; import java.io.FileReader; import java.util.Properties; /** * Verify the flexibility of reflection mechanism * java Write the code again. On the basis of not changing the original java code, you can instantiate different objects, which is very flexible * */ public class ReflectTest03 { public static void main(String[] args) throws Exception { //User user =new User(); //The following code is flexible. The code does not need to be changed. You can modify the configuration file. After modification, you can create different instance objects //Read classInfo through IO stream Properties file FileReader reader = new FileReader("classInfo.properties"); //Create attribute class object Map Properties pro = new Properties(); //load pro.load(reader); //Close flow reader.close(); //Get value through key String className = pro.getProperty("className"); System.out.println(className); //Instantiate objects through reflection mechanism Class c=Class.forName(className); Object obj=c.newInstance(); System.out.println(obj); } }
1.6 Class.forName() method call
package reflect; /** * Class.forName()What happened to the method * Remember the key points: * If you just want the static code block of a class to execute, other code blocks will not execute * You can use: class Forname ("full class name") * The execution of this method will lead to: class loading, static code block execution when class loading */ public class ReflectTest04 { public static void main(String[] args) { //Class. The execution of the forname() method will result in: class loading try { Class.forName("reflect.MyClass"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class MyClass{ //If the static method block is executed, the class must be loaded static { System.out.println("MyClass The static code block of the class is executed"); } }
2. Get path
FileReader reader = new FileReader("classInfo.properties");
The disadvantage of this method is poor portability. The default current path in IDEA is the root of project.
This code assumes that if you leave the IDEA and change to another location, the current path may not be the root of the Project, and the path will be invalid at this time.
package getPath; import java.io.FileNotFoundException; import java.io.FileReader; /** * Study the following path problems */ public class AboutPath { public static void main(String[] args) throws FileNotFoundException { //The disadvantage of this method is poor portability. The default current path in IDEA is the root of project. //This code assumes that if you leave the IDEA and change to another location, the current path may not be the root of the Project, and the path will be invalid at this time. //FileReader reader=new FileReader("classInfo2.properties"); //It's not good to use the absolute path in the above line of code, because the program may be put on the Linux system in the future, and Linux does not have Disk c or disk d, so it's better to use the following method /** * Next, let's talk about a common path. Even if the code changes location, it is still common to write in this way * Note: the premise of using the following general method is that this file must be in the classpath. * What is classpath? All methods under src are under the classpath [remember it] * src Is the root path of the class */ /* Explanation: Thread.currentThread() Current thread object getContextClassLoader()Is the method of the current object, which can get the loader object of the class of the current thread getResource() [Get resources] this is the method of the classloader object. The classloader of the current thread loads resources from the root path of the class by default */ String path=Thread.currentThread().getContextClassLoader().getResource("classInfo2.properties").getPath(); /* * Using the above code, you can get the absolute path of a file * /C:/Users/jlkjlk/IdeaProjects/Thread/out/production/Thread/classInfo2.properties * The absolute path obtained by this method is universal */ System.out.println(path); //Get dB Absolute path of the properties file (the default path starts from the root path of the class) String path2=Thread.currentThread().getContextClassLoader().getResource("getPath/Test/db.properties").getPath(); System.out.println(path2); } }
2.1 direct return by stream
package reflect; import java.io.InputStream; import java.util.Properties; public class IOPropertiesTest { public static void main(String[] args) throws Exception { //Get the absolute path of a file!! /*String path=Thread.currentThread().getContextClassLoader().getResource("classInfo2.properties").getPath(); FileReader reader=new FileReader(path);*/ //Directly return in the form of stream, which is equivalent to the combination of the above two lines of code InputStream reader=Thread.currentThread().getContextClassLoader().getResourceAsStream("classInfo2.properties"); Properties pro=new Properties(); pro.load(reader); reader.close(); //Get value through key String className=pro.getProperty("className"); System.out.println(className); } }
Note: the paths previously used in IO stream and Thread multithreading should use Thread currentThread(). getContextClassLoader(). getResource("classInfo2.properties"). getPath();
This method can be directly returned as a stream, which can be used under different operating systems
However, this method must be in the classpath to use this method!
2.2 resource binder
java. A resource binder is provided under the util package to obtain the contents of the property configuration file.
When using this method, the property configuration file XXX proper. Ties must be placed under the classpath.
package reflect; import java.util.ResourceBundle; /** * java.util A resource binder is provided under the package to obtain the content in the attribute configuration file * When using this method, the property configuration file XXX proper. Ties must be placed under the classpath. */ public class ResourceBundleTest { public static void main(String[] args) { //Resource binders can only bind XXX proper. Ties, and this file must be in the classpath. The file extension must be properties //And when writing the path, the extension name behind the path cannot be written ResourceBundle bundle=ResourceBundle.getBundle("classInfo2"); ResourceBundle bundle1=ResourceBundle.getBundle("getPath/Test/db"); String className=bundle.getString("className"); String className1=bundle1.getString("className"); System.out.println(className); System.out.println(className1); } }
3. Class loader (extension)
3.1 class loader overview
3.2 introduction to three loaders
1. First, load through the "start class loader"
Note: start the class loader to load specifically: D:\java\lib\rt.jar
The core libraries in jd rt.jar are
2. If the startup classloader cannot be loaded, it will be loaded through the extended classloader
Note: the extension class loader is specially loaded: D:\java\lib\ext
3. If not loaded in the extension class loader, it will be loaded through the application class loader
Note: the application class loader specifically loads the classes in the classpath.
3.3 parental appointment mechanism
4. Reflection properties
4.1 get field
package bean; /** * Reflection attribute Field */ public class Student { //File is translated into a field, which is actually a property / member //The four fileds adopt different access control permission modifiers private String name; protected int age; boolean sex; public int no; public static final double MATH_PI=3.141592; }
package reflect; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * Get file * Reflect all fields in the Student class */ public class ReflectTest05 { public static void main(String[] args) throws Exception { //Get the entire class Class studentClass=Class.forName("bean.Student"); String className=studentClass.getName(); System.out.println("Full class name: "+className); String simpleName=studentClass.getSimpleName(); System.out.println("Simple class name: "+simpleName); //Get all public modified fields in the class and put them into the array Field[] fields=studentClass.getFields(); System.out.println(fields.length);//There is only one element in the test array //Take out this Field Field f=fields[0]; String fieldName=f.getName(); System.out.println(fieldName); //Get all fields Field[] fs=studentClass.getDeclaredFields(); System.out.println(fs.length); //ergodic for(Field field:fs){ //Gets the list of modifiers for the property int i=field.getModifiers(); System.out.println(i); //Can you change the above code to "string"? String modifierString= Modifier.toString(i); System.out.println(modifierString); //Gets the type of the property Class fieldType=field.getType(); //String fName=fieldType.getName(); String fName=fieldType.getSimpleName(); System.out.println(fName); //Gets the name of the property System.out.println(field.getName()); } } }
4.2 decompile file
You can directly obtain the properties of a class through decompilation
package reflect; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * Decompile the attribute file of a class through the reflection mechanism */ public class ReflectTest06 { public static void main(String[] args) throws ClassNotFoundException { //This is created to splice strings StringBuilder s=new StringBuilder(); // Class studentClass=Class.forName("bean.Student"); Class studentClass=Class.forName("java.lang.Integer"); s.append(Modifier.toString(studentClass.getModifiers())+" class "+studentClass.getSimpleName()+"{\n"); Field[] fields=studentClass.getDeclaredFields(); for(Field field:fields){ s.append("\t"); s.append(Modifier.toString(field.getModifiers())); s.append(" "); s.append(field.getType().getSimpleName()); s.append(" "); s.append(field.getName()); s.append(";\n"); } s.append("}"); System.out.println(s); } }
4.3 accessing object properties through reflection mechanism (key)
package reflect; import bean.Student; import java.lang.reflect.Field; /** * Must master: * How to access the properties of a java object through reflection mechanism * Assign a value to the attribute to get the value of the attribute */ public class ReflectTest07 { public static void main(String[] args) throws Exception { //If you don't use reflection mechanism, how to access the properties of an object Student s=new Student(); //Assign values to attributes s.no=111; //Read attribute value System.out.println(s.no); //How to access an object's property (set get) using reflection mechanism Class studentClass=Class.forName("bean.Student"); Object obj=studentClass.newInstance();//obj is the Student object (the bottom layer calls the parameterless constructor) //Get properties are distinguished by name //Get no attribute Field noFile=studentClass.getDeclaredField("no"); //Assign a value to the no attribute of obj(Student object) /** * Although the reflection mechanism is used, the three elements are still indispensable * Element 1: obj object * Element 2: no attribute * Element 3: assignment * Note: the reflection mechanism makes the code complex, but flexible, which is worth it */ noFile.set(obj,11);//Assign a value to the no attribute of the obj object //Read the value of the property //Two elements: get the value of no attribute of ob object System.out.println(noFile.get(obj)); //Can I access private properties? Field nameField=studentClass.getDeclaredField("name"); //If you want to access private properties, you need to break the encapsulation (the disadvantage of reflection), which is not safe nameField.setAccessible(true); nameField.set(obj,"java"); System.out.println(nameField.get(obj)); } }
5. Reflection method (emphasis)
5.1 variable length parameters
package reflect; /** * Variable length parameter * int...args Variable length parameter * The syntax is: type (Note: it must be 3 points) * * 1,The number of parameters required for variable length parameters is: 0~N * 2,Variable length degree must be in the last position in the parameter list, and only one variable length parameter can appear */ public class ArgsTest { public static void main(String[] args) { m(); m(10); m(20); //Compilation error //m("abc"); m2(100); m2(100,"abc"); m2(200,"abc","def"); m3("ab","de","kk","ff"); String[] strs={"a","b","c"}; m3(strs); //m3(new String [] {"I", "yes", "China", "China", "people"})// It's not necessary. Just assign a value directly m3("I","yes","in","country","people"); } public static void m(int ...args){ System.out.println("m The method is executed"); } // public static void m2(String... args1,int... args2) {} / / an error will be reported, public static void m2(int a,String... args1){} public static void m3(String... args){ //Args has a length attribute, indicating that args is an array! //Variable length parameters can be viewed as an array for(int i=0;i<args.length;i++){ System.out.println(args[i]); } } }
5.2 reflection method
package reflect; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * As an understanding content: (not required to master) * Reflection Method */ public class ReflectTest08 { public static void main(String[] args) throws Exception{ //Get class Class userServiceClass=Class.forName("bean.UserService"); //Get all methods (including private ones) Method[] methods=userServiceClass.getDeclaredMethods(); System.out.println(methods.length); //Traversal Method for(Method method:methods){ //Get modifier list System.out.println(Modifier.toString(method.getModifiers())); //Gets the return value type of the method System.out.println(method.getReturnType().getSimpleName()); //Get method name System.out.println(method.getName()); //Method modifier list (a method may have multiple parameters, so the return value should be a Class array) Class[] parameterTypes=method.getParameterTypes(); for(Class parameterType:parameterTypes){ System.out.println(parameterType.getSimpleName()); } } } }
5.3 decompile Method
package reflect; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class ReflectTest09 { public static void main(String[] args) throws Exception { StringBuilder s=new StringBuilder(); Class userServiceClass=Class.forName("java.lang.String"); s.append(Modifier.toString(userServiceClass.getModifiers())+" class "+userServiceClass.getSimpleName()+" {\n"); Method[] methods=userServiceClass.getDeclaredMethods(); //public boolean login(String name,String password){ for(Method method:methods){ s.append("\t"); s.append(Modifier.toString(method.getModifiers())); s.append(" "); s.append(method.getReturnType().getSimpleName()); s.append(" "); s.append(method.getName()); s.append("("); //parameter list Class[] parameterTypes=method.getParameterTypes(); for(Class parameterType:parameterTypes){ s.append(parameterType.getSimpleName()); s.append(","); } if(s.charAt(s.length()-1)==','){ s.deleteCharAt(s.length()-1); } s.append("){}\n"); } s.append("}"); System.out.println(s); } }
5.4 calling methods through reflection mechanism (key points)
package reflect; import bean.UserService; import java.lang.reflect.Method; /** * How to call an object's method through reflection mechanism? (key points must be mastered) * Call method element analysis: * Element 1: userService object * Element 2: login method name * Element 3: argument list * Element 4: return value */ public class ReflectTest10 { public static void main(String[] args) throws Exception{ //No reflection mechanism UserService userService=new UserService(); boolean loginSuccess=userService.login("admin","123"); System.out.println(loginSuccess?"Login successful":"Login successful"); //Use reflection mechanism to call the method of an object (through method name and formal parameters) Class useServiceClass=Class.forName("bean.Student"); //create object Object obj=useServiceClass.newInstance(); //Get Method Method loginMethod=useServiceClass.getDeclaredMethod("login",String.class,String.class); //The most important method of reflection mechanism must be remembered Object retValue=loginMethod.invoke(obj,"admin","123"); } }
5.5 decompile Constructor
package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; /** * Decompile the Cons of a class */ public class ReflectTest11 { public static void main(String[] args) throws Exception{ StringBuilder s=new StringBuilder(); Class vipClass=Class.forName("bean.Vip"); s.append(Modifier.toString(vipClass.getModifiers())); s.append(" class "); s.append(vipClass.getSimpleName()); s.append("{\n"); //By construction method Constructor[] constructors=vipClass.getDeclaredConstructors(); for(Constructor constructor:constructors){ s.append("\t"); s.append(Modifier.toString(constructor.getModifiers())); s.append(" "); s.append(vipClass.getSimpleName()); s.append("("); //Splicing parameters Class[] parameterTypes=constructor.getParameterTypes(); for(Class parameterType:parameterTypes){ s.append(parameterType.getSimpleName()); s.append(","); } //Deletes the character at the last subscript position //if(parameterTypes.length>0){ // s.deleteCharAt(s.length()-1) // } if(s.charAt(s.length()-1)==','){ s.deleteCharAt(s.length()-1); } s.append("){}\n"); } s.append("}"); System.out.println(s); } }
5.6 reflection mechanism call construction method
Remember to override toString in the Vip class
package reflect; import bean.Vip; import java.lang.reflect.Constructor; /** * More important than the previous example */ public class ReflectTest12 { public static void main(String[] args) throws Exception{ //No reflection mechanism is used Vip v1=new Vip(); Vip v2=new Vip(110,"xutao","2003-3-6",true); //How do you create objects using reflection Class c=Class.forName("bean.Vip"); //Call the parameterless constructor Object obj=c.newInstance(); System.out.println(obj); //What about calling a constructor with parameters? //Step 1: get the construction method with parameters first Constructor con=c.getDeclaredConstructor(int.class,String.class,String.class,boolean.class); //Step 2: call the constructor new object Object newObj=con.newInstance(110,"jj","2022-3-6",true); System.out.println(newObj); //Get parameterless construction method Constructor con2=c.getDeclaredConstructor(); Object newObj2=con2.newInstance(); System.out.println(newObj2); } }
5.7 get parent class and parent interface
package reflect; public class ReflectTest14 { public static void main(String[] args) throws Exception{ //String example Class stringClass=Class.forName("java.lang.String"); //Get the parent class of String Class superclass=stringClass.getSuperclass(); System.out.println(superclass); //Get all interfaces implemented by the String class (a class can implement multiple interfaces) Class[] interfaces=stringClass.getInterfaces(); for(Class in:interfaces){ System.out.println(in.getName()); } } }
6. Annotation
6.1 use of custom annotation
package annotation; /** * 1,Annotation, or annotation type (note not / /) * 2,An annotation is a reference data type. After compilation, it also produces XXX Class file * 3,How to customize annotations? Syntax format? * [Modifier list] @ interface annotation type name{ * * } * 4,How and where are annotations used? * First: when using annotation, the syntax format is @ annotation type name * Second: annotations can appear on classes, attributes, methods, variables, etc It can also appear on annotation types * * By default, annotations can appear anywhere */ @MyAnnotation public class AnnotationTest01 { @MyAnnotation private int no; @MyAnnotation private AnnotationTest01(){} @MyAnnotation public static void m1(){ @MyAnnotation int i=0; } @MyAnnotation public void m2(@MyAnnotation String name){ } @MyAnnotation public static void main(String[] args) { } } @MyAnnotation interface MyInterface{ } @MyAnnotation enum Season{ SPRING,SUMMER,AUTUMN,WINTER }
6.2 JDK built-in annotation
6.3 how to define and use annotations
package annotation; /** * About the Override annotation under JDK lang package * Source code: * public @interface Override{ * * } * * * @Override This annotation can only annotate methods * @Override This annotation is referenced by the compiler and has nothing to do with the runtime * If any method in java has this annotation, the compiler will perform compilation check. If this method is not a method that rewrites the parent class, the compiler will report an error */ public class AnnotationTest02 { @Override public String toString() { return "toString"; } }
6.4 yuan notes
RUNTIME can be read by the reflection mechanism
6.5 Deprecated annotation
package annotation; /** * @Deprecated Indicates that this class is obsolete */ public class AnnotationTest03 { public static void main(String[] args) { AnnotationTest03 at=new AnnotationTest03(); at.doSome(); } @Deprecated public void doSome(){ System.out.println("do something"); } @Deprecated public static void doOther(){ System.out.println("do other"); } } class T{ public static void main(String[] args) { AnnotationTest03 at=new AnnotationTest03(); at.doSome(); AnnotationTest03.doOther(); try { Class c=Class.forName("java.util.Date"); Object obj=c.newInstance();//This method JDK8 is not outdated } catch (Exception e) { e.printStackTrace(); } } }
6.6 attributes defined in notes
package annotation.annotation2; public @interface MyAnnotation { /** * We can usually define attributes in annotations. The following is the name attribute of MyAnnotation. * It looks like a method, but we actually call it the attribute name * @return */ String name(); String color(); int age() default 25;//Property to specify the default value }
package annotation.annotation2; public class MyAnnotationTest { //The reason for the error. If there is an attribute in an annotation, the attribute must be assigned a value /*@MyAnnotation public void doSome(){ } */ //@Myannotation (attribute name = attribute value) //Specify attribute value @MyAnnotation(name="java",color = "red")//If default is specified and the default value is specified, the attribute value does not need to be specified public void doSome(){ } }
6.7 the annotation attribute name is value
When the annotation attribute name is value and there is only one attribute, value can be omitted
package annotation.annotation3; public @interface MyAnnotation { /** * Specify a value attribute */ String value(); //String email(); }
package annotation.annotation3; /** * If the attribute name of an annotation is value and there is only one attribute, value can be omitted during assignment */ public class MyAnnotationTest { //Error reason: no attribute value is specified /*@MyAnnotation() public void doSome(){} */ @MyAnnotation(value = "hehe") public void doSome(){ } @MyAnnotation("haha") public void doOther(){ } }
6.8 when the attribute is an array
package annotation.annotation4; public @interface MyAnnotation { /** * What type of attribute can be in the annotation * The type of attribute can be byte short int float double boolean char String Class enumeration type and its array */ int value1(); String value2(); int[] value3(); String[] value4(); Season value5(); Season[] value6(); Class parameterType(); Class[] parameterTypes(); }
package annotation.annotation4; public @interface OtherAnnotation { //Age attribute int age(); /* Mailbox address attribute, supporting multiple */ String[] email(); /** * Season array. Season is an enumeration type * @return */ Season[] seasonArray(); }
package annotation.annotation4; public class OtherAnnotationTest { @OtherAnnotation(age=25,email={"zhangsan@123.com","zhangsan@sohu.com"},seasonArray = {Season.SPRING,Season.SUMMER,Season.AUTUMN,Season.WINTER}) public void doSome(){ } //If there is only one element in the array, braces can be omitted @OtherAnnotation(age=25,email = "zhangsan@123.com",seasonArray = Season.AUTUMN) public void doOther(){ } }
6.9 get annotations on classes through reflection
package annotation.annotation5; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //Only this annotation is allowed. Only classes and methods can be annotated @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) //I hope this annotation can be reflected to @Retention(RetentionPolicy.RUNTIME) //@Retention(RetentionPolicy.SOURCE) / / this annotation is only saved in the java source file and cannot be reflected public @interface MyAnnotation { String value() default "jx"; }
package annotation.annotation5; @MyAnnotation("jx1") public class MyAnnotationTest { //@MyAnnotation / / no int i; //@MyAnnotation public MyAnnotationTest(){} @MyAnnotation public void doSome(){ // @MyAnnotation / / no int i; } }
package annotation.annotation5; public class ReflectAnnotationTest { public static void main(String[] args) throws Exception{ //Get this class Class c=Class.forName("annotation.annotation5.MyAnnotationTest"); //Judge whether there is @ MyAnnotation on the class System.out.println(c.isAnnotationPresent(MyAnnotation.class)); if(c.isAnnotationPresent(MyAnnotation.class)){ //Get the annotation object MyAnnotation myAnnotation=(MyAnnotation) c.getAnnotation(MyAnnotation.class); System.out.println("Class"+myAnnotation); //How to get the properties of the annotation object? It's no different from calling the interface (the object has been obtained, just call it directly) String value=myAnnotation.value(); System.out.println(value); } //Judge whether this annotation exists on the String class Class stringClass=Class.forName("java.lang.String"); System.out.println(stringClass.isAnnotationPresent(MyAnnotation.class)); } }
6.10 obtaining annotations on methods by reflection
package annotation.annotation6; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { /* * username attribute */ String username(); /* password attribute */ String password(); }
package annotation.annotation6; import java.lang.reflect.Method; public class MyAnnotationTest { @MyAnnotation(username = "admin",password = "123") public void doSome(){ } public static void main(String[] args) throws Exception{ //Get the annotation information above the doSome() method of MyAnnotationTest Class c=Class.forName("annotation.annotation6.MyAnnotationTest"); Method doSomeMethod=c.getDeclaredMethod("doSome"); //Determine whether this annotation exists on the method if(doSomeMethod.isAnnotationPresent(MyAnnotation.class)){ MyAnnotation myAnnotation=doSomeMethod.getAnnotation(MyAnnotation.class); System.out.println(myAnnotation.password()); System.out.println(myAnnotation.username()); } } }
6.11 role of annotation in development
example:
package annotation.annotation7; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //Indicates that this annotation can only be on a class @Target(ElementType.TYPE) //The annotation can be retrieved by the reflection mechanism @Retention(RetentionPolicy.RUNTIME) public @interface Id { } //This annotation @ Id is used to label the class. The marked class must have an Id attribute of type int, otherwise an exception will be reported
package annotation.annotation7; @Id public class User { int id; String name; String password; }
package annotation.annotation7; /** * Custom exception */ public class HasNotIdPropertyException extends RuntimeException{ public HasNotIdPropertyException(){} public HasNotIdPropertyException(String s){ super(s); } }
package annotation.annotation7; import java.lang.reflect.Field; public class Test { public static void main(String[] args) throws Exception{ //Get class Class userClass=Class.forName("annotation.annotation7.User"); boolean isOk=false;//Give a default tag //Judge whether there is Id annotation on the class if(userClass.isAnnotationPresent(Id.class)){ //When a class is annotated with @ id, it is required that there must be an id attribute of type int in the class. If there is no exception, it will be reported //Gets the properties of the class Field[] fields=userClass.getDeclaredFields(); for(Field field:fields){ if("id".equals(field.getName())&&"int".equals(field.getType().getSimpleName())){ //Indicates that this class is a legal class. If there is @ Id annotation, there must be int type in this class isOk=true; break; } } //Whether the interpretation is legal if(!isOk){ throw new HasNotIdPropertyException("cover Id There must be one annotation in the class to be annotated int Of type properties id Attribute!"); } } } }