4

I want to pass a collection of classes which extend Throwable to a method. However, my attempt fails to compile in Netbeans with jdk1.6.0_39:

package com.memex.sessionmanager;

import java.util.Collection;
import java.util.Collections;

public class GenericsDemo
{
    public void foo(Collection<Class<? extends Throwable>> c)
    {
    }

    public void bar()
    {
        foo(Collections.singleton(RuntimeException.class));
    }
}

The compiler says foo(java.util.Collection<java.lang.Class<? extends java.lang.Throwable>>) in com.memex.sessionmanager.GenericsDemo cannot be applied to (java.util.Set<java.lang.Class<java.lang.RuntimeException>>).

I can make it compile by changing the calling code to:

foo(Collections.<Class<? extends Throwable>>singleton(RuntimeException.class));

but I'd rather not force clients to write this obtuse generic type. Is it possible to write a method which will take any collection of classes which subtype Throwable?

EDIT:

Someone fixed the above example with the method signature:

public <T extends Throwable> void foo(Collection<Class<T>> c) {}

But I'm now having problems using the parameter. Specifically, I want to assign it to a field, like this:

package com.memex.sessionmanager;

import java.util.Collection;
import java.util.Collections;

public class GenericsDemo
{

    private Collection<Class<? extends Throwable>> throwables;

    public <T extends Throwable> void foo(Collection<Class<T>> c)
    {
        throwables = c;
    }

    public void bar()
    {
        foo(Collections.singleton(RuntimeException.class));
    }
}

But the compiler says:

incompatible types
found   : java.util.Collection<java.lang.Class<T>>
required: java.util.Set<java.lang.Class<? extends java.lang.Throwable>>
MikeFHay
  • 8,562
  • 4
  • 31
  • 52
  • Related: [incompatible types and fresh type-variable](http://stackoverflow.com/questions/20543966/incompatible-types-and-fresh-type-variable) – Paul Bellora Jan 28 '14 at 17:23

2 Answers2

6

Use

public <T extends Throwable> void foo(Collection<Class<T>> c) {}
Someone
  • 551
  • 3
  • 14
  • Sorry for so many edits; I kept messing up the formatting. I wish people would wait before downvoting. :L – Someone Jan 28 '14 at 15:34
  • This was very prompt and fixed my example, thank you. But I'm now having trouble using the parameter. I've edited the question. – MikeFHay Jan 28 '14 at 15:59
  • @MikeFHay So you want to pass it the set returned from Collections.singleton? – Someone Jan 28 '14 at 16:05
  • Sorry the example is contrived. I want to pass it any collection of `Throwable` Classes (including the `Set>` returned by `Collections.singleton` in my example). I then want to assign that Collection to a field. – MikeFHay Jan 28 '14 at 16:10
4

This should work on Java 7:

import java.util.Collection;
import java.util.Collections;

public class Generics {
  public void foo(Collection<? extends Class<? extends Throwable>> c) { 
  }

  {
    foo(Collections.singleton(RuntimeException.class));
  }
}
McDowell
  • 107,573
  • 31
  • 204
  • 267