AbstractDeferred implements Deferred<T> { @Override public Class<T> getDeferredClass() { Class<?> clazz = this.getClass(); Type type = clazz.getGenericSuperclass(); if (type instanceof ParameterizedType) { return (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; } else { throw new RuntimeException("Can determine the type of the DeferredClass: " + this); } }  @Override Class<T> getDeferredClass();  }
@Test public void shouldDetermineTypeOfAbstractDeferred() { Deferred<String> deferred = new AbstractDeferred<String>() { @Override public String get() throws TemporarilyUnavailableException, PermanentlyUnavailableException { return "Hello"; } }; Class<String> classOfDeferred = deferred.getDeferredClass(); assertThat(classOfDeferred, equalTo(String.class)); }