Java反射、自定义注解Demo
本文主要尝试使用反射、自定义注解,实现简单的Demo,所有代码均可直接复制使用。(反射和注解是Java框架不可或缺的一部分,我们应该熟练掌握这部分知识!)
本文的代码结构如下:
代码如下:
类People
包含公有字段、私有字段、公有方法、私有方法
package com.cocoa.dao;
public class People {private String county;private String peoplePrivateFiled1;private int peoplePrivateFiled2;public String peoplePublicFiled1;public String peoplePublicFiled2;public People() {}public People(String county, String peoplePrivateFiled1, int peoplePrivateFiled2, String peoplePublicFiled1, String peoplePublicFiled2) {this.county = county;this.peoplePrivateFiled1 = peoplePrivateFiled1;this.peoplePrivateFiled2 = peoplePrivateFiled2;this.peoplePublicFiled1 = peoplePublicFiled1;this.peoplePublicFiled2 = peoplePublicFiled2;}private void peoplePrivate(){System.out.println("people private method -- print");}public void peoplePublic(){System.out.println("people public method -- print");}
}
类Student
包含公有字段、私有字段、公有方法、私有方法
package com.cocoa.dao;import com.cocoa.myAnnotation.PrivateMethod;
import com.cocoa.myAnnotation.PublicMethod;public class Student extends People implements Sport{public int studentPublicField1;public String studentPublicField2;private int studentPrivateField1;private String studentPrivateField2;public Student(){}public Student( int studentPublicField1, String studentPublicField2, int studentPrivateField1, String studentPrivateField2) {this.studentPublicField1 = studentPublicField1;this.studentPublicField2 = studentPublicField2;this.studentPrivateField1 = studentPrivateField1;this.studentPrivateField2 = studentPrivateField2;}private void studentPrivateMethod1(){System.out.println("student private method1 -- print");}@PrivateMethod({"123", "123"})private void studentPrivateMethod2(int age){System.out.print(age + " = ");System.out.println("student private method2 -- print");}@PublicMethodpublic void studentPublicMethod(){System.out.println("student public method -- print");}public static void studentStaticPublicMethod(int age){System.out.println("student studentStaticPublicMethod -- print");}public People setStudentPublicMethodReturn(){return new People();}@Overridepublic void playBadminton() {System.out.println("student playBadminton");}@Overridepublic void playfootball() {System.out.println("student playfootball");}
}
接口Sport
package com.cocoa.dao;public interface Sport {public void playBadminton();public void playfootball();
}
自定义注解@PrivateMethod
package com.cocoa.myAnnotation;import java.lang.annotation.*;@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrivateMethod {String[] value() default "";
}
自定义注解@PublicMethod
package com.cocoa.myAnnotation;import java.lang.annotation.*;@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PublicMethod {String value() default "";
}
类ReflectDemo1
执行方法,获取入参数量、入参类型
package com.cocoa.reflectDemo;import com.cocoa.dao.Student;
import java.lang.reflect.*;/*** 执行 方法,拿到方法上的注解,执行方法,获取入参数量、入参类型*/
public class ReflectDemo1 {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {Student student = new Student();Class<?> aClass = student.getClass();Method[] declaredMethods = aClass.getDeclaredMethods();for (Method method : declaredMethods){String name = method.getName();System.out.println("method的name = " + name);// 拿到方法的入参数量int parameterCount = method.getParameterCount();System.out.println("method的入参数量 = " + parameterCount);if (parameterCount == 0){// 将方法的访问权限设为公有,绕过方法的访问控制method.setAccessible(true);// 执行方法method.invoke(student);}else if (parameterCount == 1){// 将方法的访问权限设为公有,绕过方法的访问控制method.setAccessible(true);// 执行方法method.invoke(student, 18);}// 拿到方法的修饰符int modifiers = method.getModifiers();System.out.println(Modifier.toString(modifiers));Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters){Type parameterizedType = parameter.getParameterizedType();System.out.println("method入参的基本信息 = " + parameter + ",修饰符 = " + parameterizedType.getTypeName());}System.out.println("---------------------------");}}
}
类ReflectDemo2
拿到字段,包括修饰符,修改字段
package com.cocoa.reflectDemo;import com.cocoa.dao.Student;
import java.lang.reflect.*;/*** 拿到字段 的相关内容,包括修饰符、修改字段*/
public class ReflectDemo2 {public static void main(String[] args) throws IllegalAccessException {Class<?> aClass = Student.class;// 拿到本类 和 父类的所有 public字段Field[] fields = aClass.getFields();for (Field field : fields){System.out.println(field);}System.out.println("---------------------------");// 拿到本类所有字段,包含public 和 privateField[] declaredFields = aClass.getDeclaredFields();Student student = new Student();for (Field field : declaredFields){// 输出字段的所有信息System.out.println(field);// 输出字段的名字String name = field.getName();System.out.println(name);// 拿到字段的修饰符int modifiers = field.getModifiers();System.out.println(Modifier.toString(modifiers));// 拿到字段的类型Type type = field.getType();System.out.println(type.getTypeName());// 给字段赋值field.setAccessible(true);if (type.equals(int.class) ){field.set(student, 11);}else {field.set(student, "test");}System.out.println("---------------------------");}System.out.println(student.studentPublicField1);System.out.println(student.studentPublicField2);}
}
类ReflectDemo3
执行类的static方法
package com.cocoa.reflectDemo;import com.cocoa.dao.Student;import java.lang.reflect.*;/*** 反射 执行 类的static方法*/
public class ReflectDemo3 {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {Class<?> aClass = Student.class;// 执行Student类的static方法Method[] declaredMethods = aClass.getDeclaredMethods();for (Method method : declaredMethods){int modifiers = method.getModifiers();if (Modifier.isStatic(modifiers)){System.out.println(method.getName());method.invoke(null, 19);}}}
}
类ReflectDemo4
拿到方法的返回值,并判断返回值的类型等
package com.cocoa.reflectDemo;import com.cocoa.dao.People;
import com.cocoa.dao.Student;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** 反射 拿到 方法的返回值*/
public class ReflectDemo4 {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {Class<?> aClass = Student.class;// 执行Student类的static方法Method[] declaredMethods = aClass.getDeclaredMethods();for (Method method : declaredMethods){Class<?> returnType = method.getReturnType();if (returnType.equals(void.class)){System.out.println(method.getName() + " 没有返回值");}else {System.out.print(method.getName() + " 有返回值,为: ");System.out.println(returnType);// 执行 有返回值的 方法Student student = new Student();Object invoke = method.invoke(student);if (invoke instanceof People){People p = (People) invoke;p.peoplePublic();}}}}
}
类ReflectDemo5
测试自定义注解
package com.cocoa.reflectDemo;import com.cocoa.dao.Student;
import com.cocoa.myAnnotation.PrivateMethod;
import com.cocoa.myAnnotation.PublicMethod;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** 使用自定义注解*/
public class ReflectDemo5 {public static void main(String[] args){Class<?> aClass = Student.class;// 执行Student类的static方法Method[] declaredMethods = aClass.getDeclaredMethods();for (Method method : declaredMethods){// 获取方法上的自定义注解Annotation[] annotations = method.getAnnotations();for (Annotation annotation : annotations){// 用于判断方法上的注解是PublicMethod吗System.out.println(annotation.annotationType().equals(PublicMethod.class));// 拿到注解的缩写类名System.out.println("方法" + method.getName() + "注解为:" + annotation.annotationType().getSimpleName());System.out.println("输出注解@PrivateMethod的value: ");if (annotation.annotationType().equals(PrivateMethod.class)){PrivateMethod annotation2 = (PrivateMethod) annotation;System.out.print("注解的value = { ");for (String s : annotation2.value()){System.out.print(s + " ");}System.out.println("}");}}}}
}
类ReflectDemo6
获取类的父类的方法
package com.cocoa.reflectDemo;import com.cocoa.dao.Student;
import com.cocoa.myAnnotation.PrivateMethod;
import com.cocoa.myAnnotation.PublicMethod;import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;/*** 获取父类的所有方法*/
public class ReflectDemo6 {public static void main(String[] args){Class<?> aClass = Student.class;Class<?> superclass = aClass.getSuperclass();// 拿到父类Method[] declaredMethods = superclass.getDeclaredMethods();for (Method method : declaredMethods){System.out.println(method.getName());}}
}
类ReflectDemo7
获取类的接口信息,获取类上的注解
package com.cocoa.reflectDemo;import com.cocoa.dao.Student;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;/*** 获取 类的接口信息*/
public class ReflectDemo7 {public static void main(String[] args){Class<?> aClass = Student.class;// 获取类的接口Class<?>[] interfaces = aClass.getInterfaces();for (Class<?> interface1 : interfaces){System.out.println(interface1.getSimpleName());Method[] declaredMethods = interface1.getDeclaredMethods();System.out.println("--------------------");for (Method method : declaredMethods){System.out.println(method.getName());}}// 获取类的注解信息Annotation[] annotations = aClass.getAnnotations();}
}