Iterable for both generic and raw type

179 views Asked by At

Without using generic types I have the following which works fine:

public class OC_GuillotinePacker implements Iterable<OC_GuillotinePacker> {
    @Override
    public Iterator<OC_GuillotinePacker> iterator() {
        // code that returns a new Iterator
    }
}

Which allows me to loop like this:

for (OC_GuillotinePacker gp : packer) {

}

I updated my code so I can store objects by it's generic type. Now it's like:

public class OC_GuillotinePacker<T> implements Iterable<OC_GuillotinePacker<T>> {
    @Override
    public Iterator<OC_GuillotinePacker<T>> iterator() {
        // code that returns a new Iterator
    }
}

The problem is when I create a new OC_GuillotinePacker like:

packer = new OC_GuillotinePacker(0, 0, width, height); 

Then I can't loop anymore like this:

for (OC_GuillotinePacker gp : packer) {

}

It gives me a incompatible types warning. Requires is OC_GuillotinePacker<> and found is java.lang.Object.

Is it possible to make it so that both is possible? So a raw for each loop and one with a generic type.

1

There are 1 answers

0
rgettman On BEST ANSWER

When you made your OC_GuillotinePacker class generic, with type parameter T, your declaration became raw.

packer = new OC_GuillotinePacker(0, 0, width, height);

When you use a raw type, type erasure occurs, such that the iterator() method now returns a raw Iterator, which returns Objects. An Object can't be assigned to a OC_GuillotinePacker, hence the error.

When creating your OC_GuillotinePacker, supply a type argument or use the diamond operator to infer the type from the packer variable declaration.

packer = new OC_GuillotinePacker<>(0, 0, width, height);

This way, the iterator() method will return OC_GuillotinePacker<YourType> objects to use in your enhanced for loop.

for (OC_GuillotinePacker<YourType> gp : packer) {

}