-2

I am writing a method which is passed a Class as an argument, like this:

public void doStuff(Class<?> clazz) {
    /* do stuff */
}

I can then call the method like this:

doStuff(FooBar.class);

How do I enforce at the compiler level that the argument can only be a class which implements a particular interface?

I’ve tried the following—

public <T extends FooInterface> void doStuff(Class<T> clazz) {
    /* do stuff */
}

—but get a compiler error for the following statement:

doStuff(FooBar.class); // FooBar implements FooInterface

How do I do this correctly?

user149408
  • 5,385
  • 4
  • 33
  • 69

2 Answers2

1

I tried your statement but it seems to work. Please have a look at the code below. I don't know the exact class definitions, but here in this case

t.doStuff(Foo.class)

works but

t.doStuff(Faa.class)

does not

public class Test{
public <T extends FooInterface> void doStuff(Class<T> clazz) {
    /* do stuff */
}

public static void main(String[] args) {
    Test t = new Test();
    t.doStuff(Foo.class); //This one compiles fine
    //g.doStuff(Faa.class);  <-- This line gives error
}
}

interface FooInterface{

}

class Foo implements FooInterface{

}

class Faa{

}
0

Turns out the code I tried was in fact correct, and the compiler error (that is, Eclipse underlining the call in red) was a result of a missing try/catch block around the call.

There are two possible ways to achieve the desired result:

public <T extends FooInterface> void doStuff(Class<T> clazz) {
    /* do stuff */
}

Or, less elaborate:

public void doStuff(Class<? extends FooInterface> clazz) {
    /* do stuff */
}
user149408
  • 5,385
  • 4
  • 33
  • 69