当前位置: 首页 > 知识库问答 >
问题:

使用反射或类似的东西在Java中获取子方法的注释

西门靖琪
2023-03-14

例如,我有一个stacktrace:

调用

方法a()-

在我的示例中,ClassC: method C()用@Cacheable注释。我需要在ClassFinal: Method odD()中得到这个注释,如下所示:

    public void MethodD() {
        Cacheable cacheable = ...
    }

我已经使用反射做到了这一点,但它不适用于过载:

    public static <T extends Annotation> T getStacktraceAnnotation(Class<T> type) {
        int currStack = 0;
        T result = null;
        
        //
        //
        StackTraceElement[] stackTraceElementArray = Thread.currentThread().getStackTrace();
        
        //
        //
        for (java.lang.StackTraceElement curr : stackTraceElementArray) {
            try {
                Method[] methods = Class.forName(curr.getClassName()).getMethods();
                
                for (Method currMethod : methods) 
                    if (currMethod.getName().equals(curr.getMethodName())) {
                        result = currMethod.getAnnotation(type);
                        if (result != null) break;
                    }
                //
                //
                if (result != null || currStack++ > 6) break;
            } catch(Exception exc) {
                // Nothing!
            }
        }
        //
        //
        return result;
    }

我的程序的真正堆栈:

fff.commons.serverless.abstracts.v2.AbstractCommonIntegrationHttp.sendGet(AbstractCommonIntegrationHttp.java:320) 
fff.commons.serverless.abstracts.v2.Teste.a(Teste.java:14) 
fff.commons.serverless.abstracts.v2.Teste.main(Teste.java:18)

Teste。a(Teste.java:14)以@cacable
标记,我需要在sendGet(AbstractCommonIntegrationHttp.java:320)中获得这个附加值

我的注释:

@Retention(RUNTIME)
@Target({ TYPE, METHOD })
@Inherited
public @interface Cacheable {
    int secs() default 15;
}

共有1个答案

朱啸
2023-03-14

我强烈建议使用StackWalker代替:

private static final StackWalker SW = StackWalker
        .getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);

public static <T extends Annotation> T getStacktraceAnnotation(Class<T> type) {
    return SW.walk(s -> s.map(sf -> getMethodAnnotation(type, sf)).filter(Objects::nonNull)
            .findFirst()).orElseThrow();
}

private static <T extends Annotation> T getMethodAnnotation(Class<T> annotationClass,
        StackFrame sf) {
    try {
        return sf.getDeclaringClass()
                .getDeclaredMethod(sf.getMethodName(), sf.getMethodType().parameterArray())
                .getAnnotation(annotationClass);
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    }
}

StackWalker。StackFrame包含区分不同重载所需的信息——即方法类型。
AStackTraceElement仅包含行号——如果您自己解析相应的类文件,这可能就足够了——但这很快就失控了。

 类似资料:
  • 问题内容: 我正在尝试制作一个按钮,以便用户单击它时,按住鼠标按钮时它会更改其样式。如果在移动浏览器中触摸它,我也希望它以类似的方式更改其样式。对我来说,看似显而易见的事情是使用CSS:active伪类,但这没有用。我尝试了:focus,但是也没有用。我尝试:hover,它似乎起作用了,但是当我将手指从按钮上移开后,它仍然保持了样式。所有这些观察都是在iPhone 4和Droid 2上进行的。 有

  • 问题内容: 我正在尝试使用反射来获取在类中显式声明的所有公共方法(因此将无法工作,因为它也可以获取超类方法)。我可以用 只能从该类中获取方法,但是我只想使用公共方法。 在这一点上,我试图抓住修饰符并据此执行某些操作,但是由于某些原因,调试器中显示的修饰符值与修饰符值输出不同。例如,我有一个私有方法,尽管“ modifiers”值在调试器中显示,但在输出时却显示。奇怪的。还有另一种获取公共方法的方法

  • 问题内容: 场景 我正在用Java编写涉及汽车的程序。 注意:我已尽最大可能简化了此方案,以使其更加通用和易于理解。 我实际上不是在开车。 我创建了一个类,它是对象的集合。 该对象具有一个(double)和一个(int)。构造函数将年份作为参数,例如: 这是棘手的部分…汽车必须具有某种类型(比如说Corvette或Clunker)。克尔维特(克尔维特)的车子为and,Cl子(Clunker)的车子

  • 我有一个具有以下结构的对象列表: 我需要一个方法,如果任何对象的someBoolean字段设置为true,它将返回整数-1,否则返回someInteger的最小值。 我可以用simple for loop来做,有没有一种方法可以用一个流来做呢?我的问题是anyMatch和min()都在终止流。

  • 有了这个jdk代码在, java编译器只有注释声明,它足够智能,可以检测错误(编译时): 在下面的问题代码中。 的注释声明刚刚编译为, 它只不过是一个。 所以 语法是否帮助java编译器在编译时检测上述错误?

  • 问题内容: 刚刚在玩CSS中的属性。 我想让所有鼠标事件都看不到,除了。 因此,所有单击命令都将转到其下一个,但div可以报告鼠标是否在其上方。 谁能告诉我是否可以做到? HTML: CSS: 问题答案: 我认为仅凭CSS不可能实现您的目标。但是,正如其他贡献者所提到的那样,在JQuery中做起来很容易。这是我的操作方法: 的HTML CSS(不变) jQuery查询