(Note.. I have restructured the example to more closely match the use case I am working on)
I have the following interface defined:
public interface Interceptor {
<T> T intercept (Invocation<T> invocation);
interface Invocation<T> {
T proceed();
}
}
This simplest implementation of this would be something like:
class TestInterceptor {
static class Line {int x1, y1, z1, x2, y2, z2;}
static class Color {int r, g, b;}
static class Renderer {
Interceptor interceptor;
Renderer (Interceptor interceptor) {this.interceptor = interceptor;}
void draw (Supplier<Line> lineSource, Supplier<Color> colorSource) {
Line thisLine = interceptor.intercept(lineSource::get);
Color thisColor = interceptor.intercept(colorSource::get);
// do the drawing
}
}
void drawSomething () {
Renderer render = new Renderer(getInterceptor());
render.draw( () -> createLine(), () -> createColor() );
}
Line createLine () {return new Line(/*something*/);}
Color createColor () {return new Color(/*something*/);}
Interceptor getInterceptor () {
return new Interceptor() {
@Override
<T> T intercept (Invocation<T> invocation) {
/* would like to do this:
if (invocation.returnType = Line) {
return new MyLIne();
} else {
return invocation.proceed();
} */
return invocation.proceed();
}
}
}
}
Notice the comment in getInterceptor() that I would like to take different actions (including not calling the lambda) based on what the lambda is going to return. I have tried everything I can think of to get the actual type behind the parameterized type T but keep drawing a blank. Can anyone help me out here?
Here are some of the things I've tried
Class<?> wclass = interceptor.getClass();
Method method = wclass.getMethod("proceed", new Class<?>[]{});
Class<?> rtype = method.getReturnType(); //getName() always returns "java.lang.Object"
Type gtype = method.getGenericReturnType();
Class<?> gtclass = gtype.getClass(); //getName() always returns "java.lang.Class"
String gtname = gtype.getTypeName()); //always returns "java.lang.Object"
I am actually trying to create a "Remote Launcher" for JUnit5 so I can use Maven SureFire to run tests in a separatly launched and configured OSGi "container" (way overloaded term but don't get me started). Except for the getInterceptor() method, all of the sample code above is a simplification of existing Junit5 code and not anything I can change.
(Ideally, I would integrate the new Remote Launcher into PaxExam which seems to have stagnated.)
You can make the interface use a type parameter just like how Lists work in Java.
Then your implementations can be specific implementations such as a string worker like so: