public TypeSerializer<T> getElementSerializer() {
        // call getSerializer() here to get the initialization check and proper error message
        final TypeSerializer<List<T>> rawSerializer = getSerializer();
        if (!(rawSerializer instanceof ListSerializer)) {
            throw new IllegalStateException();
        }

        return ((ListSerializer<T>) rawSerializer).getElementSerializer();
    }
@Test
    void testSerializerDuplication() {
        // we need a serializer that actually duplicates for testing (a stateful one)
        // we use Kryo here, because it meets these conditions
        TypeSerializer<String> statefulSerializer =
                new KryoSerializer<>(String.class, new SerializerConfigImpl());

        ListStateDescriptor<String> descr = new ListStateDescriptor<>("foobar", statefulSerializer);

        TypeSerializer<String> serializerA = descr.getElementSerializer();
        TypeSerializer<String> serializerB = descr.getElementSerializer();

        // check that the retrieved serializers are not the same
        assertThat(serializerB).isNotSameAs(serializerA);

        TypeSerializer<List<String>> listSerializerA = descr.getSerializer();
        TypeSerializer<List<String>> listSerializerB = descr.getSerializer();

        assertThat(listSerializerB).isNotSameAs(listSerializerA);
    }