Home > database >  How to check if the type is instanceof an interface in java?
How to check if the type is instanceof an interface in java?

Time:11-09

I have a class (CreateAccountRequest) that implement an interface(Iloggable), the interface has no method, Just for marking purpose.

public interface Iloggable {}    

public class CreateAccountRequest implements Iloggable{
 //some private fields, getters and setters
}

In my custom RequestBodyAdviceAdapter class, trying to check if the request is an instance of Iloggable, to proceed or ignore the request (for instance do the logging or not )

I know we can use instanceOf operator to check if an object implements an interface or not and the unit test as below approve it:

@Test
void CreateAccountRequest_Object_Instance_Of_Iloggable_Test() {
    CreateAccountRequest request = new CreateAccountRequest();
    assertTrue(request instanceof Iloggable);
}

But in RequestBodyAdviceAdapter supports method the result is false or true all the time, I tried different ways to distinguish if the parameter implement the interface or not

@ControllerAdvice
public class CustomRequestBodyAdviceAdapter extends RequestBodyAdviceAdapter {
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
    //if(methodParameter.getParameterType().isInstance(Iloggable.class)) //return false all the time
    //if(methodParameter.getParameter().getType().isInstance(Iloggable.class))// return false all the time
    if(methodParameter.getParameter().getClass().isInstance(Iloggable.class))// return false all the time
    // if(type instanceof Iloggable)// return false all the time
    //if(type.getClass().isInstance(Iloggable.class)) //return true all the time
    //if(type != null && Iloggable.class.isAssignableFrom(type.getClass()))//return false all the time
      return true;
    return false;
}
    //other override methods
}

For removing any doubt, I put a snapshot of the debugging in the support method:

enter image description here

CodePudding user response:

You want to make sure that type represents a class that implements Illoggable.

@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
    if ( type instanceof Class ) {
        cls = ( Class ) type;
        result = Iloggable.class.isAssignableFrom( cls );
    } else {
        result = false;
    }
    return result;
}

CodePudding user response:

In this case type is a java.lang.reflect.Type (instance) and not an CreateAccountRequest (instance;)

You could get more lucky with:

if (type instanceof Class) { // type != null
  Class<?> aClazz = (Class<?>) type;
  return Iloggable.class.isAssignableFrom(aClazz);
}

Class.isAssignableFrom(...)-javadoc-17

Type -> Class

In depth:

  • if(type instanceof Iloggable) //always false, because type is the
    // (java.lang.reflect.)Type(->class) (occasionally) of the Iloggable and not/ever an instance of it.
    
  • if(type.getClass().isInstance(Iloggable.class)) //equivalent to 
    // java.lang.reflect.Type.class.isInstance(Iloggable.class)
    // always false, except when Iloggable *implements* Type (pervert, but possible!;)
    
  • Iloggable.class.isAssignableFrom(type.getClass()) //incorporates 
    // my "wrong assumptions" on type... type.getClass() would 
    // evaluate to java.lang.reflect.Type.class, which is similar to bullet 2
    

But I assume (when correctly used -> experiment) some MethodParameter methods should also lead to the desired. Especially:

CodePudding user response:

Try following comparison, target.getTypeName()==Iloggable.class.getTypeName()

  • Related