I am trying to have a Flux generic converter using generic types in Java 8. I am basing my code on this answer. Ths idea is basically to implement this specific converter String
-> Integer
:
public Flux<Integer> createFluxConverterStringToInt(String[] data) {
Flux<Integer> stringFlux = Flux
.just(data)
.map(value -> Integer.parseInt(value))
.log();
return stringFlux;
}
to a typed converter String
-> to whatever type I want. So I am creating a class FluxAndMonoGeneric
of type <OUT>
with a constructor FluxAndMonoGeneric(Class<OUT> typeArgumentClass)
, and returning a method public Flux<OUT> createFluxConverter(String[] data)
. I was thinking to create multiples entries like this : this.typeArgumentClass.isInstance(Integer.class)
on the map
call but with different class types. But it is not working even for an Integer.
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Slf4j
public class FluxAndMonoGeneric<OUT> {
private final Class<OUT> typeArgumentClass;
public FluxAndMonoGeneric(Class<OUT> typeArgumentClass) {
this.typeArgumentClass = typeArgumentClass;
}
public Flux<OUT> createFluxConverter(String[] data) {
Flux<OUT> stringFlux = Flux
.just(data)
.map(value -> {
// NEVER ENTERS ON THIS IF
if (this.typeArgumentClass.isInstance(Integer.class))
return this.typeArgumentClass.cast(Integer.parseInt(value));
// ALWAYS ENTERS ON THIS ELSE AND STRING CANNOT BE CASTED TO INTEGER
else return this.typeArgumentClass.cast(value);
})
.log();
return stringFlux;
}
public Mono<OUT> createMonoConverter(String data) {
Mono<OUT> integerMono = Mono.just(data)
.map(value -> this.typeArgumentClass.cast(value))
.log();
return integerMono;
}
}
The I am getting the error: java.lang.ClassCastException: Cannot cast java.lang.String to java.lang.Integer
when I test using this unit test.
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
public class FluxAndMonoGenericTest {
// this works.
@Test
void testCreateGenericFluxWithString() {
String expect = "Spring,Spring Boot,Reactive Spring";
String delimiter = ",";
String[] messages = expect.split(delimiter);
FluxAndMonoGeneric<String> myFluxGenericTest = new FluxAndMonoGeneric<String>(String.class);
Flux<String> stringFlux = myFluxGenericTest.createFluxConverter(messages);
StepVerifier.create(stringFlux)
.expectNext(messages[0])
.expectNext(messages[1])
.expectNext(messages[2])
.verifyComplete();
}
// THIS DOES NOT WORK
@Test
void testCreateGenericFluxWithInteger() {
String expect = "1,1234,7654,34";
String delimiter = ",";
String[] messages = expect.split(delimiter);
Integer[] expectedMessages = new Integer[]{1, 1234, 7654, 34};
FluxAndMonoGeneric<Integer> myFluxGenericTest = new FluxAndMonoGeneric<Integer>(Integer.class);
Flux<Integer> stringFlux = myFluxGenericTest.createFluxConverter(messages);
StepVerifier.create(stringFlux)
.expectNext(expectedMessages[0])
.expectNext(expectedMessages[1])
.expectNext(expectedMessages[2])
.expectNext(expectedMessages[3])
.verifyComplete();
}
}