面试题答案
一键面试1. 获取带注解的方法
- 定义注解:
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 { String value() default ""; }
- 定义包含带注解方法的类:
public class MyClass { @MyAnnotation("example") public void myMethod(String param) { System.out.println("Method called with param: " + param); } }
- 使用反射获取带注解的方法:
import java.lang.reflect.Method; public class AnnotationReflection { public static void main(String[] args) { try { Class<?> clazz = MyClass.class; Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(MyAnnotation.class)) { MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); System.out.println("Found method with annotation: " + method.getName()); System.out.println("Annotation value: " + annotation.value()); } } } catch (Exception e) { e.printStackTrace(); } } }
2. 传递参数并调用方法
- 继续使用上述定义的类和注解:
- 在获取到方法后传递参数并调用:
import java.lang.reflect.Method; public class AnnotationReflection { public static void main(String[] args) { try { Class<?> clazz = MyClass.class; Object instance = clazz.newInstance(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(MyAnnotation.class)) { method.setAccessible(true); method.invoke(instance, "test param"); } } } catch (Exception e) { e.printStackTrace(); } } }
这里newInstance()
创建类的实例,invoke
方法传递参数并调用方法。
3. 可能遇到的问题及解决方案
- 问题1:方法不存在或访问权限不足
- 原因:反射调用的方法可能不存在,或者方法是私有的没有访问权限。
- 解决方案:确保方法存在,可以通过
getDeclaredMethods
获取所有方法(包括私有方法),并使用setAccessible(true)
来设置可访问性。
- 问题2:参数类型不匹配
- 原因:传递给
invoke
方法的参数类型与目标方法的参数类型不一致。 - 解决方案:在调用
invoke
方法前,确保传递的参数类型与目标方法参数类型匹配,必要时进行类型转换。
- 原因:传递给
- 问题3:注解未在运行时保留
- 原因:如果注解的
RetentionPolicy
不是RUNTIME
,在运行时无法通过反射获取到注解。 - 解决方案:确保注解定义时
RetentionPolicy
设置为RUNTIME
。
- 原因:如果注解的