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

时间:2018-12-04 12:24:27

标签: java reflection annotations

据说这不是一个新问题,但是我很难找到解决方案,因为对此的大多数答案都涉及到有问题的方法,而不是公开的。

上下文

有一个名为reflection的程序包,其中定义了注释以及UITester类,后者使用类注释和方法注释。名为gui的其他程序包包含类MinimalUI,该类随后测试对UITester的访问,其方法以及相应的注释值。但是我遇到了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(); 
}

UITester

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

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 );
    }
}

MinimalUI

最后,在同一包中声明了一个最小的UI类,该类实现了Gui接口。我只发布了相关的测试方法,因为否则此示例将变得有点大。以下代码是方法MinimalUI#testUI。它需要读取为UITester设置的注释,并根据结果进行操作。该实现是极简主义的,并且缺少保障措施,这很好,因为这是一个沙箱项目,我正在其中测试要转移到生产中的模式。代码:

@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!" );
    }
}

问题

运行MinimalUI#testUI导致抛出NoSuchMethodException,到目前为止,我仍然不明白为什么。引发异常的确切行是Method possiblyLockedMethod = UITester.class.getMethod( "printIfAvailable" );

  • 注释会以某种方式影响getMethod的行为吗?类声明可能会有所更改吗?
  • 方法printIfAvailable被声明为public,那么为什么找不到它?注释会以某种方式影响public状态吗?
  • 两个注释都用@Retention( RetentionPolicy.RUNTIME )注释,这是否有可能阻止在加载类或进行任何此类操作时定义函数?

我认为这很简单,我很想念。目前没有我可以找到的错别字,那怎么了?

2 个答案:

答案 0 :(得分:1)

调用UITester.class.getMethod( "printIfAvailable" )意味着您正在尝试获取名为printIfAvailable的方法,该方法需要 no 参数({{1}的parameterTypes参数}是var-arg)。

但是,您的方法是使用getMethod参数声明的。你应该用

String

答案 1 :(得分:1)

您现在的问题是您使用的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.
 * ...