Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding to a Generic Set passed into a method

Let us say I have the following classes:

  • Animal
  • Cat
  • Dog
  • Cow

Animal is the base class, cat, dog, and cow each subclass it.

I now have a Set<Cat>, Set<Dog> and Set<Cow> each of these are used in the same way, so it makes sense to make a generic function to operate on them:

private boolean addObject(Animal toAdd, Animal defVal, Set<? extends Animal> vals)

This works great, I can freely pass in my Sets with no problem.

The problem appears: I can't attempt to add the Animal toAdd to parameter vals. Googling reveals that if I change the method to read:

private boolean addObject(Animal toAdd, Animal defVal, Set<? super Animal> vals)

I will be able to add the Animal to parameter vals. This works, except now, I can't pass in my subclassed my Sets of Cats, Dogs, and Cows. Further research tells me that the following works, with no warnings to boot:

private <T> boolean addObject(T toAdd, T defVal, Set<? super T> vals)

The problem being, I need to be able to perform method calls that Animal's all have. This is easily gotten around using a simple cast:

((Animal)toAdd).getAnimalType()

Is there any way around this problem so I can keep the generic functionality, and not require casting? Aside from making my Sets all Sets of the Base Type, Animal in the case of this example?

like image 659
Legowaffles Avatar asked Mar 08 '13 11:03

Legowaffles


People also ask

How do you pass a generic argument in Java?

When we declare an instance of a generic type, the type argument passed to the type parameter must be a reference type. We cannot use primitive data types like int, char. Test<int> obj = new Test<int>(20);

Which one of the following statement is true regarding the generic method?

Which of the following allows us to call generic methods as a normal method? Explanation: Type inference, allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets.

How do I return a generic response in Java?

(Yes, this is legal code; see Java Generics: Generic type defined as return type only.) The return type will be inferred from the caller. However, note the @SuppressWarnings annotation: that tells you that this code isn't typesafe. You have to verify it yourself, or you could get ClassCastExceptions at runtime.


1 Answers

Good research, you were almost there. You just need to add an upper bound to T.

private <T extends Animal> boolean addObject(T toAdd, T defVal, Set<? super T> vals)
like image 104
Ben Schulz Avatar answered Oct 25 '22 03:10

Ben Schulz