为什么以下代码打印堆栈跟踪,为什么 return 语句中的 a.toString() 没有给出错误或异常?
Why do the following code prints the stack trace and why is a.toString() in the return statement not giving an error or exception?
完整代码如下-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
class A2<T> {
T ob;
A2(T ob) {
this.ob = ob;
}
@Annos(str="T example")
T retob() {
return ob;
}
@Override
public String toString() {
Annotation a = null;
try {
Class<?> c = this.getClass();
Method m = c.getMethod("retob");
a = m.getAnnotation(Annos.class);
}catch(NoSuchMethodException NSMe) {
NSMe.printStackTrace();
}
return a==null?"EMPTY":a.toString();
}
public static void main(String args[]) {
System.out.println(new A2<Integer>(2).toString());
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface Annos {
String str();
}
如果我重写了 toString()
方法,那么 return 语句和 main 方法中的 a.toString()
如何工作?
这是输出 -
java.lang.NoSuchMethodException: A2.retob()
at java.base/java.lang.Class.getMethod(Class.java:2227)
at A2.toString(A2.java:20)
at A2.main(A2.java:28)
EMPTY
为什么获取不到方法retob
?
解决方法是改变
Method m = c.getMethod("retob");
到
Method m = c.getDeclaredMethod("retob");
这是必需的,因为您的 retob
方法不是 public。
来自 the documentation of getMethod:
[The class's] declared public instance and static methods as returned by getDeclaredMethods() and filtered to include only public methods that match given name and parameterTypes
这意味着 getMethod
使用 getDeclaredMethod
但如果不是 public
则忽略该方法。使用 getDeclaredMethod
直接解决了这个问题。
关于您关于 toString 的问题:
return a==null?"EMPTY":a.toString();
仍然有效,因为 a
是 null
。这就是返回 "EMPTY"
的原因。
完整代码如下-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
class A2<T> {
T ob;
A2(T ob) {
this.ob = ob;
}
@Annos(str="T example")
T retob() {
return ob;
}
@Override
public String toString() {
Annotation a = null;
try {
Class<?> c = this.getClass();
Method m = c.getMethod("retob");
a = m.getAnnotation(Annos.class);
}catch(NoSuchMethodException NSMe) {
NSMe.printStackTrace();
}
return a==null?"EMPTY":a.toString();
}
public static void main(String args[]) {
System.out.println(new A2<Integer>(2).toString());
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface Annos {
String str();
}
如果我重写了 toString()
方法,那么 return 语句和 main 方法中的 a.toString()
如何工作?
这是输出 -
java.lang.NoSuchMethodException: A2.retob()
at java.base/java.lang.Class.getMethod(Class.java:2227)
at A2.toString(A2.java:20)
at A2.main(A2.java:28)
EMPTY
为什么获取不到方法retob
?
解决方法是改变
Method m = c.getMethod("retob");
到
Method m = c.getDeclaredMethod("retob");
这是必需的,因为您的 retob
方法不是 public。
来自 the documentation of getMethod:
[The class's] declared public instance and static methods as returned by getDeclaredMethods() and filtered to include only public methods that match given name and parameterTypes
这意味着 getMethod
使用 getDeclaredMethod
但如果不是 public
则忽略该方法。使用 getDeclaredMethod
直接解决了这个问题。
关于您关于 toString 的问题:
return a==null?"EMPTY":a.toString();
仍然有效,因为 a
是 null
。这就是返回 "EMPTY"
的原因。