2

I have this Event class that I’d like to make more generic, so I can return other types than just User, Is there a way of auto casting inside this event class or should I do it everytime outside of it?.

Do you have suggestions?

What I have

public class Event {
  protected String name;
  protected Pair<String, User> event;

  public String getName() {
    return event.first;
  }

  public User getData() {
    return event.second;
  }

  public Event(String name, User data) {
    event = Pair.create(name, data);
  }
}

What I want

public class Event<T> {
  protected String name;
  protected Pair<String, T> event;

  public String getName() {
    return event.first;
  }

  public T getData() {
    return event.second; //cast to type
  }

  public Event(String name, T data) {
    event = Pair.create(name, data);
  }
}
Leonardo Deleon
  • 2,577
  • 5
  • 15
  • 22
  • 2
    There is no need for cast (but we don't have `Pair` definition), as (it seems) `second` is of type `T` and `getData()` return a `T`. – Jean-Baptiste Yunès Jun 12 '17 at 09:51
  • 2
    I don't get what you want exactly. The second code you posted should work if I'm not missing anything. – André Stannek Jun 12 '17 at 09:52
  • Why do you think you need to cast from ``T`` to ``T``? – f1sh Jun 12 '17 at 09:52
  • If I call `getData()` it will return Object, not `T` :( – Leonardo Deleon Jun 12 '17 at 09:52
  • 3
    That is most likely because you are using a [raw type](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) in other code that you didn't show us. Don't do that - use generics all the way. In other words: wherever you are using this, use `Event` instead of just `Event`. – Jesper Jun 12 '17 at 09:52
  • Hey @Jesper I actually found the problem, I was posting this event in a RxBus `public void post(Event event) { relaySubject.accept(event); }` – Leonardo Deleon Jun 12 '17 at 10:06
  • I need to find a way of posting a generic type event in a non generic bus now – Leonardo Deleon Jun 12 '17 at 10:06

2 Answers2

3

When you create an instance of Event<User>, T gets automatically "substituted" to User So public T getData() actually returns an User and there is no need for casting

RaffoSorr
  • 405
  • 1
  • 5
  • 14
2

I'm not sure how you defined Pair, but the following works without any casting required:

public class Pair<F,S>
{
  F first;
  S second;
  public Pair (F first, S second) {
    this.first=first;
    this.second=second;
  }
  public static <F,S> Pair<F,S> create (F first, S second) {
    return new Pair<F,S> (first,second);
  }
}

public class Event<T> {
  protected String name;
  protected Pair<String, T> event;

  public String getName() {
    return event.first;
  }

  public T getData() {
    return event.second;
  }

  public Event(String name, T data) {
    event = Pair.create (name, data); // note you can use the Pair constructor directly 
                                      // instead of calling the static create method
  }
}

Which can be used, for example, like this:

Event<Integer> intEvent = new Event<> ("name", 5);
Integer data = intEvent.getData ();
Eran
  • 387,369
  • 54
  • 702
  • 768