0

I am writing a custom iterator but I am seeing different warnings in my Java code.

Here is my code:

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class CustomIterator<E> implements Iterator<E> {
    public static void main(String[] args) {
        List<String> a = Arrays.asList("alpha", "beta", "gamma");
        List<Integer> b = Arrays.asList(1, 2, 3);

        // Type safety: The constructor CustomIterator(Iterator...) belongs to the raw type CustomIterator. References to generic type CustomIterator<E> should be parameterized
        CustomIterator it = new CustomIterator(a.iterator(), b.iterator());
        // some logic
    }

    // Type safety: Potential heap pollution via varargs parameter iterators
    public CustomIterator(Iterator<E>... iterators) {
        // some logic
    }

    @Override
    public boolean hasNext() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public E next() {
        // TODO Auto-generated method stub
        return null;
    }
}

I just added the warnings as comments in above code.

It occurs at 2 places:

// Type safety: The constructor CustomIterator(Iterator...) belongs to the raw type CustomIterator. References to generic type CustomIterator<E> should be parameterized
CustomIterator it = new CustomIterator(a.iterator(), b.iterator());

and also here:

// Type safety: Potential heap pollution via varargs parameter iterators
    public CustomIterator(Iterator<E>... iterators) {
        // some logic
    }

I can use @SuppressWarnings({ "unchecked", "rawtypes" }) to suppress them but I want to know why I am getting these and how to avoid them without suppressing.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
learner
  • 6,062
  • 14
  • 79
  • 139
  • You probably can't avoid suppressing them. What you are doing has real type-safety issues. There is actually no type `E` that you could safely instantiate this ... apart from `Object`. In other words, you don't get any benefit from using generics here. – Stephen C Aug 11 '19 at 11:07
  • You need a declaration like `@SafeVarargs public CustomIterator(Iterator extends E>... iterators)` – Holger Aug 12 '19 at 08:50

1 Answers1

1

You can't safely pass two Iterators of different element types (Iterator<String> and Iterator<Integer> to your CustomIterator constructor.

If you hadn't used raw types (as in CustomIterator it), the compiler would have told you so. The following, for example, won't pass compilation:

CustomIterator<Integer> it = new CustomIterator<Integer>(a.iterator(), b.iterator());
Eran
  • 387,369
  • 54
  • 702
  • 768
  • 2
    @Michael no, `CustomIterator it = new CustomIterator(a.iterator(), b.iterator());` doesn't pass compilation (unless you change `a` and `b` to `List`). – Eran Aug 11 '19 at 11:03