5

What is the equivalent in Java for this C# declaration ?

public class AsyncThreadPool<T, K> where T : IAsyncThread<K> {

and IAsyncThread is an interface

public interface IAsyncThread<T> 
{
    T GetAsyncUsedObject(); 
    void StartAsyncRequest();    
}

I have tried :

public class AsyncThreadPool<T extends IAsyncThread<K>, K  >

But is not correct, as T implements IAsyncThread<K> not extends it.

And I need in this class to use T.StartAsyncRequest() or similar

In C# it is:

T asyncThread = default(T);
asyncThread.StartAsyncRequest()
Alex
  • 2,213
  • 4
  • 32
  • 44
  • `T asyncThread = default(T);`: This line is going to give you some trouble. Since Java implements generics with erasure, it doesn't know what type `T` is at runtime. – StriplingWarrior Aug 10 '12 at 15:07
  • If you really need to create an instance of `T`, you will have to pass an argument of `Class` somehow in order to create that new object. – atamanroman Aug 10 '12 at 15:10
  • 2
    When using `extends` in generics like that it doesn't matter if T `extends` or `implements` the latter class/interface. The keyword is still `extends`. – Matt Razza Aug 10 '12 at 15:11

3 Answers3

10

Generic constraints in Java only have two options, extends and super, and there is no difference in that case between extending and implementing. Your method declaration code should work as is.

For instantiation, you will have to do a pattern where you use the class of T to create it. Because you can't directly use T.class, you could create a factory, like corsiKa suggested, if you need reusability of the creation patterns, or you can just pass in a Class<T> into the constructor for your class and keep that instance around.

public class AsyncThreadPool<T extends IAsyncThread<K>, K>{ 
    private final Class<T> clazz;
    public AsyncThreadPool(Class<T> clazz){
        this.clazz = clazz;
    }       
    public void Start() throws InstantiationException, IllegalAccessException{          
        T instance = clazz.newInstance();
        instance.StartAsyncRequest();
    }
}

It may also be important to note that, in C#, using default(T) for a class or interface will produce a null reference and so your original example is incorrect.

Chris Hannon
  • 4,134
  • 1
  • 21
  • 26
5

Your <T extends IAsyncThread<K>> is correct. Even though the class itself implements, not extends, the terminology for the generic definition is extends. If you wanted, you could use <T extends Object & IAsyncThread<K>> or <T extends Object, IAsyncThread<K>> but would be unnecessary.

For creating a member of type T, the only thing you really have at your disposal is to use a factory object.

public class AsyncThreadPool<T extends IAsyncThread<K>, K> {
    private final AsyncThreadFactory<T> factory;
    public ASyncThreadPool(AsyncThreadFactory<T> factory) {
        this.factory = factory;
    }
    public void foo() {
        T t = factory.createDefault();
        t.startAsyncRequest();
    }
}
corsiKa
  • 81,495
  • 25
  • 153
  • 204
2

Your code should be fine:

public class AsyncThreadPool<T extends IAsyncThread<K>, K  >

With generics, extends can mean extension or implementation.

GriffeyDog
  • 8,186
  • 3
  • 22
  • 34