简体   繁体   中英

Unable to find public method via getMethod()

Supposedly this is not a new problem however I am having trouble finding the solution, because most answers to this refer to the method in question not being public.

Context

There is a package named reflection , where annotations as well as a UITester class are defined, the latter uses a class-annotation and a method-annotation. A different package named gui contains a class MinimalUI which then tests access to UITester , its methods and the respective annotation values. However I am running into a NoSuchMethodException .

Code

FunctionAnnotation

The annotation is used to lock/unlock methods.

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

SampleAnnotation

Simple annotation to set some basic class properties.

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

This is the annotated class. The class declaration itself is annotated and so is one method of the class, so both annotations previously shown are used.

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

Finally there is a minimal UI class that implements the Gui interface, declared in the same package. I am posting just the relevant test method, because otherwise this sample will become a bit large. The following code is method MinimalUI#testUI . It needs to read the annotations set for UITester and behave in accordance with the results. The implementation is minimalistic and lacks safeguards, which is fine, because this is a sandbox project where I am testing patterns to be transferred to production. The code:

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

Question

Running MinimalUI#testUI results in a NoSuchMethodException being thrown, so far I do not understand why. The exact line throwing the exception is Method possiblyLockedMethod = UITester.class.getMethod( "printIfAvailable" ); .

  • Do annotations somehow influence the behavior of getMethod ? Possibly class declaration is changed somehow?
  • Method printIfAvailable is declared public , so then why is it not found? Do annotations somehow influence the public status?
  • Both annotations are annoted with @Retention( RetentionPolicy.RUNTIME ) , is it possible that this prevents the function from being defined as the class is loaded or anything of the sort?

I assume it is something simple I am missing. Currently there were no typos I was able to find, so what is going on there?

The call UITester.class.getMethod( "printIfAvailable" ) means that you're trying to get a method called printIfAvailable that takes no parameters (the parameterTypes parameter of getMethod is a var-arg).

However, your method is declared with a String parameter. You should get it with

UITester.class.getMethod( "printIfAvailable", String.class );

Your problem right now is that you're using the getMethod -method wrong. You just search for a method without any parameter. If you change it to this UITester.class.getMethod( "printIfAvailable", String.class ); it will work fine.

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.
 * ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM