1

Please help resolve an issue regarding generics. I tried many ways but it's still not working. Problem is:

public static void main(String[] args) {
    Utils.execute(new TestAction(), new TestCallBack());
}

Compiler show error:

The method execute(Action<?>, CallBack<?,Action<?>>) in the type Utils is not applicable for the arguments (ImplementClass.TestAction, ImplementClass.TestCallBack)

My classes is:
Action class:

public abstract class Action<R> {
public R getResult() {
    return null;
}
}

TestAction class is:

class TestAction extends Action<String> {
    @Override
    public String getResult() {
        return super.getResult();
    }
}

Callback class is:

public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);}

TestCallback class is:

class TestCallBack implements CallBack<String, TestAction> {

    @Override
    public void onCall(TestAction action) {

    }

}

And Utils class is:

public class Utils {
public static void execute(Action<?> action, CallBack<?, Action<?>> callback) {

}
}

Thanks a lot.

2
  • Any reason why execute 'uses' type parameters, but then again does not use them? Since you refer to them as <?>? Commented Dec 18, 2013 at 15:45
  • I made a sample to demo my issue in my app. Commented Dec 18, 2013 at 16:00

2 Answers 2

1

The second parameter of the execute method is CallBack<?, Action<?>>, and Action there means the Action class itself, subclass of it is not allowed. What you need there is - ? extends Action<?>, which means either Action or some subclass of it.

Try changing the method signature -

public static void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {

Note:

Generics are not co-variant. Take for example a method as follows -

static void method(List<Object> l) {}

And an invocation as follows is not allowed -

method(new ArrayList<String>());
Sign up to request clarification or add additional context in comments.

5 Comments

What is the reason for the difference?
@BheshGurung: That was a hint to put the explanation in your answer ;)
It doesn't work. I just copy parse it into Utils class. But now IDE show error: No enclosing instance of type ImplementClass is accessible. Must qualify the allocation with an enclosing instance of type ImplementClass (e.g. x.new A() where x is an instance of ImplementClass).
@LeoNguyen That's an unrelated error - make A a static nested class.
yes. Proplem is my class is not static. But how the way to work with non static class?
1

You need to change two things,

TestCallBack should be like this -

public static class TestCallBack implements CallBack<String, Action<String>> {
  @Override
  public void onCall(Action<String> action) {
  }
}

and, Utils should be like this -

public static class Utils {
  // You need to ensure the same type, not just try and accept anything.
  public static <T> void execute(Action<T> action, CallBack<?, Action<T>> callback) {
  }
}

or using inner classes of a class called Question -

public abstract class Action<R> {
  public R getResult() {
    return null;
  }
}

public class TestAction extends Action<String> {
  @Override
  public String getResult() {
    return super.getResult();
  }
}

public interface CallBack<R, A extends Action<R>> {
  public void onCall(A action);
}

public class TestCallBack implements CallBack<String, TestAction> {
  @Override
  public void onCall(TestAction action) {
  }
}

public class Utils {
  public void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
  }
}

public static void main(String[] args) {
  Question question = new Question();
  question.new Utils().execute(question.new TestAction(), question.new TestCallBack());
}

5 Comments

Why does TestCallBack need to change?
It work. But TestCallBack & TestAction must be static class. How the way to implement them as inner class?
@PaulBellora To ensure that the Action and Callback are actually compatible.
@LeoNguyen I did this as static inner classes. You want them as normal inner classes?
@LeoNguyen That's a different problem that you should try to solve separately from this post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.