本文主要尝试使用反射、自定义注解,实现简单的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");
}
@PublicMethod
public 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();
}
@Override
public void playBadminton() {
System.out.println("student playBadminton");
}
@Override
public 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 和 private
Field[] 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();
}
}