I'm trying to override the following methods but I can't figure out the generics mechanism:
public interface MyInterface<T extends MyGenericObject> {
public void read(long id, Callback<T> callback);
public void readAll(Callback<Collection<T>> callback);
}
public class SomeObject extends MyGenericObject {
...
}
public class MyClass implements MyInterface<SomeObject> {
#Override
public void read(long id, **????** callback) {
...
}
#Override
public void readAll(**????** callback) {
...
}
}
Could you please help me?
EDIT: I had an intermediate Interface between MyClass and MyInterface and the generic SomeObject wasnt passed all the way, that was my problem...
Just replace each T by SomeObject which is passed to MyInterface<T>.
// T has become SomeObject = put everywhere SomeObject instead of T
public class MyClass implements MyInterface<SomeObject> {
#Override
public void read(long id, Callback<SomeObject> callback) {
...
}
#Override
public void readAll(Callback<Collection<SomeObject>> callback) {
...
}
}
EDIT
You have mentioned in comment that it does not compile due of erasure problem (why you getting this error is explained in comment section), however this is not possible with code you have posted:
public interface MyInterface<T extends MyGenericObject> {
void read(long id, Callback<T> callback);
void readAll(Callback<Collection<T>> callback);
}
public interface Callback<T> {}
public class MyGenericObject {}
public class SomeObject extends MyGenericObject {}
public class MyClass implements MyInterface<SomeObject> {
#Override public void read(long id, Callback<SomeObject> callback) {}
#Override public void readAll(Callback<Collection<SomeObject>> callback) {}
}
This code compiles without any error:
import java.util.Collection;
interface Callback<T> {}
class MyGenericObject {}
interface MyInterface<T extends MyGenericObject> {
public void read(long id, Callback<T> callback);
public void readAll(Callback<Collection<T>> callback);
}
class SomeObject extends MyGenericObject { }
class MyClass implements MyInterface<SomeObject> {
#Override
public void read(long id, Callback<SomeObject> callback) {
}
#Override
public void readAll(Callback<Collection<SomeObject>> callback) {
}
}
If you are getting "read/readAll in MyClass clashes with read/readAll in MyInterface; both methods have same erasure, yet neither overrides the other", then your code is different to what you have indicated.
Pretty sure you can just use Callback<SomeObject> callback and Callback<Collection<SomeObject>> callback respectively.
Try
public class MyClass<T extends SomeObject> implements MyInterface<T> {
Now you can use T in your method implementations. You will specify the specific class when you instantiate MyClass.
Related
I have an interface like this:
public interface IEventListener
{
public <T extends MyCustomObject> void onEvent(final T object);
public <T extends MyCustomObject> void onEventTest2(final T object);
}
and in some other class that implements this interface i want call the same method but define whatever parameter i want like:
public class MyClass implements IEventListener
{
#Override
public <T> void onEvent(final Player player)
{
// My code here
}
#Override
public <T> void onEventTest2(final Item item)
{
// My code here
}
}
How can i achieve this ?
It seems very clear, now, that your generics should be on the type, not the method -- and with your edit, you'll just need multiple parameters, i.e.
interface IEventListener<T1 extends MyCustomObject, T2 extends MyCustomObject> {
void onEvent(T1 object);
void onEventTest2(T2 object);
}
public class MyClass implements IEventListener<Player, Item> {
#Override public void onEvent(Player player) { ... }
#Override public void onEventTest2(Item item) { ... }
}
There is not going to be any way you can have the generics on the methods; they must be on the type.
I want to combine the use of bounded type parameters with DI spring. That is, I would like to declare an interface:
public abstract class BaseClass {
}
public class ChildClass extends BaseClass {
}
public interface SomeInterface {
<T extends BaseClass> void update(T impl);
}
and make its implementation:
#Service
public class Impl1 extends SomeInterface {
#Override
void update(ChildClass impl) {
}
}
That is, I want to declare in the interface a general type condition for implementations and use a specific type of successor in the implementation.
Is it possible?
You can:
public interface SomeInterface<T extends BaseClass> {
void update(T impl);
}
and then:
#Service
public class Impl1 extends SomeInterface<ChildClass> {
#Override
void update(ChildClass impl) {
}
}
I have this interface:
public interface EventHandler<T extends Event> {
void handle(T event);
}
And this class implementing it:
public class MyEventHandler implements EventHandler<MyEvent> {
#Override
public void handle(MyEvent event) {
//do something
}
}
In this clase, T parameter is MyEvent, that is a concrete implementation of Event. How can obtain this using reflection?
Resolve the type of T by the generic interface. E.g.
public interface SomeInterface<T> {
}
public class SomeImplementation implements SomeInterface<String> {
public Class getGenericInterfaceType(){
Class clazz = getClass();
ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericInterfaces()[0];
Type[] typeArguments = parameterizedType.getActualTypeArguments();
Class<?> typeArgument = (Class<?>) typeArguments[0];
return typeArgument;
}
}
public static void main(String[] args) {
SomeImplementation someImplementation = new SomeImplementation();
System.out.println(someImplementation.getGenericInterfaceType());
}
PS: Keep in mind that the acutalTypeArguments are of type Type. They must not be a Class. In your case it is a Class because your type definition is EventHandler<MyEvent>.
When trying to do anything non-trivial with generics and reflection, consider Guava's TypeToken:
private interface Event {}
private interface EventHandler<T extends Event> {
void handle(T event);
}
TypeToken<?> findEventType(final Class<? extends EventHandler> handlerClass) throws Exception {
final TypeToken<? extends EventHandler> handlerTypeToken = TypeToken.of(handlerClass);
final Invokable<? extends EventHandler,Object> method = handlerTypeToken.method(EventHandler.class.getDeclaredMethod("handle", Event.class));
return method.getParameters().get(0).getType();
}
public void testExploreGuavaTypeTokens() throws Exception {
class MyEvent implements Event {}
class MyEventHandler implements EventHandler<MyEvent> {
#Override public void handle(final MyEvent event) {}
}
assertEqual(MyEvent.class, findEventType(MyEventHandler.class).getRawType());
}
(Note that the TypeToken returned by findEventType() could contain much richer type information than a Class can represent; that's why it's the caller's decision whether to simplify it via getRawType().)
Let's say I have a generic builder type:
public abstract class Builder<T> {
public abstract T build();
}
Then a Foo class and a builder for it, which extends Builder:
public class Foo {
// stuff
}
public class FooBuilder extends Builder<Foo> {
public Foo build() {
return new Foo();
}
}
I also have an abstract, generic Handler type:
public abstract class Handler<T> {
public abstract <U extends Builder<T>> void handle(U builder);
}
and finally a FooHandler:
public class FooHandler extends Handler<Foo> {
#Override
public void handle(FooBuilder builder) {
// do something
}
}
The issue is that FooHandler's handle() is not recognized as overriding Handler's handle(): Method does not override method from its superclass. Is it possible to do this?
Move the type parameter to the class level
abstract class Handler<T, U extends Builder<T>> {
public abstract void handle(U builder);
}
class FooHandler extends Handler<Foo, FooBuilder> {
#Override
public void handle(FooBuilder builder) {
// do something
}
}
Generic method :
public <T> void foo(T t);
Desired overridden method :
public void foo(MyType t);
What is the java syntax to achieve this?
A better design is.
interface Generic<T> {
void foo(T t);
}
class Impl implements Generic<MyType> {
#Override
public void foo(MyType t) { }
}
You might want to do something like this :
abstract class Parent {
public abstract <T extends Object> void foo(T t);
}
public class Implementor extends Parent {
#Override
public <MyType> void foo(MyType t) {
}
}
A similar question was answered here as well : Java generic method inheritance and override rules
interface Base {
public <T> void foo(T t);
}
class Derived implements Base {
public <T> void foo(T t){
}
}