3
public interface A {}
public interface B {}
public class Test implements A{}
public class Test2 {}

I made a method which checks if a class implements an interface. I want my method to only accept generic interfaces and not all class objects.

method

    public static boolean containsInterface(Class clazz, Class intf)
    {
    try
    {
        Validate.isTrue(intf.isInterface());
        if(clazz.isInterface())
            return JavaUtil.isClassExtending(intf, clazz);
        for(Class c : ClassUtils.getAllInterfaces(clazz))
        {
            if(JavaUtil.isClassExtending(intf, c))
                return true;
        }
    }
    catch(Throwable t)
    {
        t.printStackTrace();
    }
    return false;
}

Since Test.class & Test2.class are not interfaces on the 2d parameter I want it to have a compile error since the 2d parameter must be an interface class

containsInterface(Test.class, Test.class);
containsInterface(Test.class, Test2.class);

acceptable use of my method

containsInterface(Test2.class, A.class);
containsInterface(Test.class, B.class);

what I tried

public static boolean containsInterface(Class clazz, Class<? extends Interface> intf)

I currently check if the class in the parameter is an interface then throw an exception. I would rather force people to not be able to call the method to begin with if it's not an interface

I am aware of Annotations and Enum objects are available to use as a class signature to make sure people are using the parameters right but, I can't seem to find the one for the interface itself.

I was told generics do not support interfaces or abstract classes type is this true even in jre 9-13+

  • 2
    Can you please explain what `containsInterface()` is supposed to do? – ernest_k Jan 15 '20 at 05:35
  • it determines is a class has a specified interface. You input the interfaces class. I already have it working I just want to enforce the 2d interface parameter to be an interface – nullsector76 Jan 15 '20 at 05:54
  • It will take a few reopen votes for the question to be reopened. Just give some time. – ernest_k Jan 15 '20 at 06:05
  • And as a quick answer for you, there's no construct for enforcing *statically* that a *type* is an interface. a `Class` object will include interfaces (and enums and annotations and concrete or abstract classes, etc.) – ernest_k Jan 15 '20 at 06:09
  • You might be able to do this with a preprocessor... – dan1st Jan 15 '20 at 06:13
  • I know Enum and Annotations are useable to check for a signature in a class. Class extends Enum> Class extends Annotation> – nullsector76 Jan 15 '20 at 06:14
  • 1
    Another quick answer is to use `intf.isAssignableFrom(clazz))` (or even `instanceof`), but almost always these sorts of checks are a code smell; That's why we want to know the use case, because there's probably a better way. Also remember Generics ( like ` extends Something>`) are not available at runtime. – racraman Jan 15 '20 at 06:18
  • currently I just check to make sure it's an interface and throw a runtime exception if it's not. I thought I could make the code cleaner by using it as a signature class parameter – nullsector76 Jan 15 '20 at 06:24
  • The problem is there is not type that is a parent interface of all interfaces (except for java.lang.Object), so you cannot do Class extends ParentOfAllInterfaces> – Sean F Jan 15 '20 at 15:51
  • Not possible. If it were, `java.lang.reflect.Proxy` would probably use it. – Johannes Kuhn Apr 17 '20 at 14:03
  • @JohannesKuhn heheh i just wrote answer having this as an example xD – Antoniossss Apr 17 '20 at 14:03

2 Answers2

1

You cannot force argument to be ANY interface implementation using type control system. The same would apply if you would like to eg force only Class<?> with abstract modifier. I am not sure if that is really needed as doing simple type isInterface assert is

  1. Straigthforward
  2. Clean
  3. Robust
  4. Easy to understand
  5. Error prone
  6. Testable

JDK Engineers does not care about that either. As an perfect example of such mechanism would be used (but there is none) is JDK Dynamic Proxy creation. You can create only create proxy of an interface (or set of) but not of class.

I don't think that it is just worth of the effort to write own preporocessors. Moreover it would be not universal - as you assume that runtime type must be know at compile time - what about dynamically loaded classes etc?

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

Intefaces in java has no super class that you can use in generic mode.

If you try get the super class of an interface with reflection returns null.

public static void main (String [] args) {
        System.out.println(A.class.getSuperclass());
}

interface A {}

Output:

null
SMortezaSA
  • 589
  • 2
  • 15