Proposal: Accepting a subclass as an element type in a for loop

Jean-Louis Ardoint jlardoint at
Tue Mar 31 08:41:20 PDT 2009

You might say that all proposals are very niche, and almost all of them can be solved by writing some code (you may save some time by writing a generic comment ☺).

List<Set<Number>> foo = someMethodCall();
for ( Set<Double> set : foo ) {
   // You can't do this in java.

I don't understand your point. A List<Set<Number>> should not contain a Set<Double> if you use generics without tweaks. So what would you expect?

Anyway, thank you for your comments.

--Jean-Louis Ardoint

From: Reinier Zwitserloot [mailto:reinierz at] On Behalf Of Reinier Zwitserloot
Sent: Tuesday, March 31, 2009 5:16 PM
To: Jean-Louis Ardoint
Cc: coin-dev at
Subject: Re: Proposal: Accepting a subclass as an element type in a for loop

Why is this worthy of a language change? It's very niche.

You can solve your problem by writing 1 method, like so:

for ( Rectangle r : MyUtilityClass.filterOnType(shapes, Rectangle.class) ) {


public class MyUtilityClass {
    public static <A, B> List<B> filterOnType(Iterable<? extends A> in, Class<B> outType) {
        List<B> list = new ArrayList<B>();
        for ( A a : in )
            if ( outType.isInstance(a) ) list.add(outType.cast(a));
        return list;

Even if you disregard for a moment that if you add this, I've got about a gazillion other niche things that have about as many use cases and are about as easy to solve with a library for coin,your proposal has omitted a rather serious issue:

What would you do if you have something like:

List<Set<Number>> foo = someMethodCall();
for ( Set<Double> set : foo ) {
   // You can't do this in java.

 --Reinier Zwitserloot

On Mar 31, 2009, at 14:55, Jean-Louis Ardoint wrote:

I'm maybe a bit too late. Here's my proposal anyway.

-- Jean-Louis Ardoint

Accepting a subclass as an element type in a for loop

AUTHOR(S): Jean-Louis Ardoint



Add a filtering and downcast capability to the enhanced for statement
(a.k.a for each).


It should reduce the number of lines of code and depth of nesting in
loops. The resulting code would be more readable that what is done
currently to achieve the same goal. The meaning of such a loop is quite


Better readability and expressiveness.


More complexity in the compiler to generate a little bit more bytecode.


You can currently the same thing, yet it means adding an extra if
statement and an intermediate variable to be cast.


Here is a small not very interesting example of such a enhanced for

Shape[] shapes = ...;

for (Shape s : shapes)


If for a reason you would need to draw only the rectangles, you would
need to write:

for (Shape s : shapes) {

 if (s instanceof Rectangle)



This is not very aesthetic. If only the for loop would directly accept a
subclass as the element type and do the type checking and downcast, we
could be able to write:

for (Rectangle r : shapes)


Note that there is a subtlety w.r.t. the handling of nulls. See
Compilation below for more details



The grammar is unchanged. The equivalence between an enhanced for loop
and a regular for loop has to be changed in JLS 14.14.2.


The way enhanced loop are translated into bytecode would change
depending on whether the loop variable type is a subclass of the
iterable or array element type.

If the loop variable type is a subclass, then the loop is equivalent to:

For an expression returning Iterable<C>:

Iterable<C> cs...

for (I #i = cs.iterator(); #i.hasNext(); ) {

 C #c =;

 if (#c == null || #c instanceof D) {

   D d = (C)#c;




For an array:

C[] ca...

for (int i = 0; i < ca.length; i++) {

 C #c = ca[i];

 if (#c == null || #c instanceof D) {

   D d = (C)#c;




Note that we need to test against null to keep the same behavior as the
regular enhanced for loop.


This feature can be tested in the same way the enhanced for loop is


There is no need for library support.


No updates to the reflection APIs are needed.


No other changes are needed.


Migration of existing enhanced for loop can be done if one desires so.



This feature would not break any existing programs, since the new
feature only permits more code to be parsed than before.


Class file format does not change, so existing programs can use class
files compiled with the new feature without problems.

More information about the coin-dev mailing list