0

Consider the problem: someone needs to implement, say, java.util.Set< E > interface with his/her own class. The .add(E e) method explicitly declared to expect the object of the type denoted with the generic parameter E. However, the .remove(Objec o) method explicitly declare to accept any object.

Thinking the static typing way, one might be embarassed with such thing. He/She still needs to back up E-type objects only.

Is there an elegant way to check for the object o, given as a parameter for the remove method, to be an instance of the generic type E?

Lionishy
  • 188
  • 1
  • 2
  • 10
  • 1
    Check this solution "http://stackoverflow.com/questions/1570073/java-instanceof-and-generics" – Jorge Apr 05 '16 at 15:55
  • 1
    Related: http://stackoverflow.com/questions/104799/why-arent-java-collections-remove-methods-generic – Savior Apr 05 '16 at 15:55
  • Do you mean without repeating the name of the type parameter? Because obviously there's `if (o instanceof TheTypeParameterClass)` (not that `instanceof` is "elegant") assuming you're implementing `Set`. – T.J. Crowder Apr 05 '16 at 15:55
  • An "elegant" solution has to be generic, no doubts. – Lionishy Apr 06 '16 at 06:39
  • To inject the name of the type with a constructor is ugly solution in the sense of cohesion as implementation do not rely on any specific type. It is also an error prone solution -- type system may became unsound by accident. – Lionishy Apr 06 '16 at 06:48
  • Why would you need to do that? The reasoning behind how the API works is perhaps a bit obscure and results in an API which is maybe not the most commonsensical but there's not a huge practical value in having `remove(E e)` versus `remove(Object e)` - either the element is in the collection or it's not. The only extra value you can get with checking the type would be, potentially, to throw an IllegalArgumentException? – sisyphus Apr 08 '16 at 08:27
  • @sisyphus The main incosistence with having romeve(Object e) instead of remove(E e) is that concrete implementaion of Set, for instance MyIntegerSet extends AbstractSet, may significantly rely on the E, for instance Integer. The generics also may be restricted: MySet> implements Set. Thus, accepting Object instead of Integer may lead to unexpected or unpredictable behavior. The most safe answer is to decline, to reject any type other than E at compile time. I'm looking for the most close solution. – Lionishy Apr 08 '16 at 18:41
  • @Lionishy: There is a reason why it is `remove(Object o)` and not `remove(E o)` -- the contract for the `remove` method in `Collection` defines `remove(o)` to remove any item `e` in the collection such that `(o==null ? e==null : o.equals(e))`. If you do not accept all objects you would be potentially breaking the contract. – newacct Apr 12 '16 at 00:06
  • @newacct There's no way to accept remove(Object) and add(E) at the same time. It's just breaking the substitution principle. We all know than Java Collection is type unsound and unsafe. Moreover if we would be interested to accept any object supporting equals method with E, we had been invent Equals interface for the reomove method parameter constrains. – Lionishy Apr 14 '16 at 04:48
  • @newacct In fact, the goal is not to discuss the Java Collection drawbacks, but how to live with them. – Lionishy Apr 14 '16 at 04:54
  • >> I have never heard of these "drawbacks" << Just an example: if one has a `Set` of `Integer`s backed with the `HashSet`, the `remove((short)1)` just do not remove anything, but if a `Set` is backed with the `TreeSet` the `remove` methods throws an Exception. So, the soundness of your programm may be subject not of the interface, but the implementation. – Lionishy Apr 16 '16 at 05:50

0 Answers0