0

I have generic interface:

public interface StreamObserver<V> { void onNext(V value); } 

And have to create objects for different types (SubscribeTradesResponse and SubscribeOrderResponse):

1)

StreamObserver<SubscribeTradesResponse> getTradesResponseStream() { return new StreamObserver<SubscribeTradesResponse>() { @Override public void onNext(SubscribeTradesResponse response) { responseOnNextAction(response); } }; } 

2)

StreamObserver<SubscribeOrderResponse> getOrderResponseStream() { return new StreamObserver<SubscribeOrderResponse>() { @Override public void onNext(SubscribeOrderResponse response) { responseOnNextAction(response); } }; } 

Is it possible to make a common method getResponseStream() and pass SubscribeTradesResponse or SubscribeOrderResponse as an argument?

2 Answers 2

2

You can do even better by using lambda expressions, which will allow you to get rid of getTradesResponseStream and getOrderResponseStream:

StreamObserver<SubscribeTradesResponse> tradeObserver= response -> responseOnNextAction(response); //or StreamObserver<SubscribeTradesResponse> tradeObserver= this::responseOnNextAction; StreamObserver<SubscribeOrderResponse> orderObserver = response -> responseOnNextAction(response); //or StreamObserver<SubscribeOrderResponse> orderObserver = this::responseOnNextAction; 

That assumes you have overloaded responseOnNextAction accordingly.

But if you were to use the inner classes, you can still make the method generic:

<T> StreamObserver<T> getTradesResponseStream() { return new StreamObserver<T>() { @Override public void onNext(T response) { responseOnNextAction(response); } }; } 

But this depends on the signature of responseOnNextAction. It will work as is if the method takes an Object, but if it takes a Response of a sort, you may have to change the type parameter to
<T extends Response>

Sign up to request clarification or add additional context in comments.

2 Comments

Excelent! <T> StreamObserver<T> getResponseStream() does exact what I want. Thanks!. But how does it know what type T will be?
@suit Strictly speaking, it doesn't know. The type safety relies on the implementation of responseOnNextAction(response). The generic method is facilitating the casting, but the return value of responseOnNextAction must still be compatible.
2

You can create a common interface for the two response types:

interface TradeOrOrderResponse { } 

with

class SubscribeTradesResponse implements TradeOrOrderResponse 

and

class SubscribeOrderResponse implements TradeOrOrderResponse 

and then extend your observer-interface

public interface TOResponseObserver extends StreamObserver<V extends TradeOrOrderResponse> { void onNext(V value); } 

and if your responseOnNextAction takes that interface

void responseOnNextAction(TradeOrOrderResponse resp) 

it implements the TOResponseObserver interface, ie you can use it to handle either SubscribeTradesResponse or SubscribeOrderResponse objects.

2 Comments

I thought about class SubscribeTradesResponse implements TradeOrOrderResponse, unfortunately, this is an external library, i can't add implements to this class
@suit You could write a simple wrapper method in the interface for both classes... but then you'd probably face the same problem as you do now :/

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.