为什么以下代码打印堆栈跟踪,为什么 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(); 仍然有效,因为 anull。这就是返回 "EMPTY" 的原因。