General parameter with additional restriction through intersection types

I am writing a class to represent time series data, i.e. basically a map of pairs (Instant, T) for the general type T

 interface TimeSeries<T> { void add(Instant when, T data); } 

Some of the classes we deal with implement the interface

 interface TimeStamped { Instant getTimeStamp(); } 

and I want to provide a more convenient method in the TimeSeries interface to add such data items without specifying the time. Basically i want

 interface TimeSeries<T> { void add(Instant when, T data); default <X extends T & TimeStamped> void add(X data) { add(data.getTimeStamp(), data); } } 

but this does not seem to be allowed by the language, because I cannot use type variables in intersection types . Is there any work that is not related to giving up static security? The only thing I can come up with is

 interface TimeSeries<T> { void add(Instant when, T data); default void add(TimeStamped data) { add(data.getTimeStamp(), (T)data); } default void add(TimeStamped t, T data) { add(t.getTimeStamp(), data); } } 

add(TimeStamped t, T data) is type safe but still inconvenient.

+5
source share
1 answer

I think I understand your question. Basically, you might have a TimeSeries with some simple type that does not implement TimeStamped , but some of its subclasses. In these cases, even a workaround by @assylias does not help.

Well, I think that there is no clean solution to this problem in Java 8, and I have no experience with Java 9, but I have not noticed anything like this while reading about my new features. This means that you sacrifice safety or comfort in a static style.

It’s hard to say what is the best workaround. Basically, what we have so far:

  • The TimeStamped interface for cases when your base object already implements the TimeStamped interface, as @assylias advised.
  • Static method recommended by @cppbeginner. I don't like the syntax, although it is implied as syntactic sugar, but you get a static call. This is quite universal, although it does what you want.
  • Give up the whole idea of ​​sugar syntax and just enter it as a subordinate.
  • Give up type safety and get good code that can have unpleasant consequences.
  • Oh wait, another opportunity. Do this using the TimeStamped interface, and TimeSeries as an argument. Actually better than static, but curious from the bottom up.

I cannot decide which one is best for you, since I do not know your use case. None of them are perfect. I already ran into this problem and I did not find a super-smart solution. Another thing that I could not do is a generic listing. I mean, why not, it would be interesting if that were possible (but that is also not the case).

+1
source

Source: https://habr.com/ru/post/1272851/


All Articles