代码之家  ›  专栏  ›  技术社区  ›  Koenigsberg

无法通过GetMethod()找到公共方法

  •  1
  • Koenigsberg  · 技术社区  · 6 年前

    假设这不是一个新的问题,但是我很难找到解决方案,因为大多数对这个问题的回答都是指不公开的方法。

    语境

    有一个名为 reflection ,其中注释和 UITester 类被定义,后者使用类注释和方法注释。另一个名为 gui 包含一个类 MinimalUI 然后测试访问 乌斯特 及其方法和各自的注释值。但是我遇到了 NoSuchMethodException .

    代码

    功能说明

    注释用于锁定/解锁方法。

    package reflection;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import java.lang.annotation.ElementType;
    
    @Retention( RetentionPolicy.RUNTIME )
    @Target( {ElementType.METHOD} )
    public @interface FunctionAnnotation
    {
        boolean locked();
    }
    

    样品说明

    设置一些基本类属性的简单注释。

    package reflection;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    @Retention( RetentionPolicy.RUNTIME )
    public
    
    @interface SampleAnnotation
    {
        String name();
        String value();
        boolean output(); 
    }
    

    乌斯特

    这是带注释的类。类声明本身是注释的,类的一个方法也是注释的,因此使用了前面显示的两个注释。

    package reflection;
    
    @SampleAnnotation( name = "default", value = "[MINIMAL UI ANNOTATION] Testing.", output = true )
    public class UITester
    {
        public UITester()
        {
            System.out.println( "[UI TESTER] Created." );
        }
    
        public void print( String value )
        {
            System.out.println( "[UI TESTER] Printing: " + value );
        }
    
        @FunctionAnnotation( locked = false )
        public void printIfAvailable( String value )
        {
             System.out.println( "[UI TESTER] Printing (available): " + value );
        }
    }
    

    最低限度

    最后还有一个实现 Gui 接口,在同一个包中声明。我只是张贴相关的测试方法,因为否则这个样本会变得有点大。以下代码是方法 MinimalUI#testUI . 它需要读取的注释集 优斯特 按照结果行事。这个实现是最低限度的,并且缺乏安全保障,这是很好的,因为这是一个沙盒项目,我在其中测试要转移到生产中的模式。代码:

    @Override
    public void testUI()
    {
        UITester tester = new UITester();
        Annotation annotation = UITester.class.getAnnotation( SampleAnnotation.class );
    
        if ( annotation instanceof SampleAnnotation )
        {
            String value = ( (SampleAnnotation) annotation ).value();
    
            tester.print( value );
    
            try
            {
                Method possiblyLockedMethod = UITester.class.getMethod( "printIfAvailable" );
                Annotation methodLockCheck = possiblyLockedMethod.getAnnotation( FunctionAnnotation.class );
    
                if ( !( ( FunctionAnnotation) methodLockCheck ).locked() ) tester.printIfAvailable( value );
            }
            catch( NoSuchMethodException e ) 
            { 
                System.out.println( "[MINIMAL UI][ERROR] Cannot find method to be retrieved. Reflection failed. " + e.getMessage() );
            }
            catch( Exception e )
            {
                System.out.println( "[MINIMAL UI][ERROR] Exception during UI testing via reflection: " + e.getMessage() + " Exception: " + e.toString() );
            }
        } 
        else
        {
            System.out.println( "[MINIMAL UI][ERROR] Reflection error. Unable to read annotation!" );
        }
    }
    

    问题

    正在运行 最低测试 结果A 无粘膜乙氧基感觉 被甩了,到目前为止我还不明白为什么。引发异常的确切行是 Method possiblyLockedMethod = UITester.class.getMethod( "printIfAvailable" ); .

    • 注释是否以某种方式影响 getMethod ?类声明可能被更改了?
    • 方法 printIfAvailable 被宣布 public 那么为什么找不到呢?注释是否以某种方式影响 公众的 状态?
    • 两个注释都用注释 @Retention( RetentionPolicy.RUNTIME ) ,这是否可能阻止将函数定义为类已加载或任何类型?

    我想这是我所缺少的简单的东西。目前我找不到打字错误,那又是怎么回事?

    2 回复  |  直到 6 年前
        1
  •  1
  •   ernest_k Petronella    6 年前

    呼叫 UITester.class.getMethod( "printIfAvailable" ) 意味着您正在尝试获取一个方法 printIfAvailable 那需要 参数( parameterTypes 参数 getMethod 是var ARG。

    但是,您的方法是用 String 参数。你应该拿着它

    UITester.class.getMethod( "printIfAvailable", String.class );
    
        2
  •  1
  •   CodeMatrix    6 年前

    你现在的问题是你在使用 getMethod -方法错误。只需搜索不带任何参数的方法。如果你换成这个 UITester.class.getMethod( "printIfAvailable", String.class ); 它会很好用的。

    JavaDoc:

    /**
     * Returns a {@code Method} object that reflects the specified public
     * member method of the class or interface represented by this
     * {@code Class} object. The {@code name} parameter is a
     * {@code String} specifying the simple name of the desired method. The
     * {@code parameterTypes} parameter is an array of {@code Class}
     * objects that identify the method's formal parameter types, in declared
     * order. If {@code parameterTypes} is {@code null}, it is
     * treated as if it were an empty array.
     * ...