2

in C#, we can define a generic class A<T> where T : new(). In this code, we can create an instance of T with new T(). How does this implement in Java? I read some article which says it's impossible.

The reason that I used have a singleton patten using generic in C# like:

public static class Singleton<T> where T : new()
{
    private static T instance;

    public static T Instance
    {
        get 
        {
            if (instance == null)
            {
                instance = SingletonCreater.Instance;
            }
            return instance;
        }
    }

    static class SingletonCreater
    {
        internal static readonly T Instance = new T();
    }
}

And way to make this method more graceful?

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
Howard
  • 3,638
  • 4
  • 32
  • 39
  • by the way, you might be interested in this thread: http://stackoverflow.com/questions/75175/create-instance-of-generic-type-in-java – Alvin Apr 19 '11 at 02:00

3 Answers3

7

No you can't do new T(), since you don't know if T has a no arg constructor, and because the type of T is not present at runtime due to type erasure.

To create an instance of T, you need to have code like,

public <T> T create(Class<T> clazz) {
    try {
        //T must have a no arg constructor for this to work 
        return clazz.newInstance(); 
    } catch (InstantiationException e) {
        throw new IllegalStateException(e);
    } catch (IllegalAccessException e) {
        throw new IllegalStateException(e);
}
sbridges
  • 24,960
  • 4
  • 64
  • 71
  • I see, so I cannot implement like the way I used in C#, right? We can keep this open and see if there is any other idea. :) – Howard Apr 19 '11 at 01:19
  • 1
    in c#, how do you know that T has a no arg constructor? – sbridges Apr 19 '11 at 01:36
  • In the class definition, we have where T : new() which means this T accepts none-argument constructor :) – Howard Apr 19 '11 at 01:37
  • No-arg constructor is not an issue at all. Type erasure is. – Vladimir Dyuzhev Apr 19 '11 at 01:41
  • In this part, MS' API is more powerful I think. – Howard Apr 19 '11 at 01:47
  • @road to yamburg, even without type erasure, you cant do new T(), since you can't ensure that T has a no arg constructor. – sbridges Apr 19 '11 at 01:56
  • @sbridges - The compiler can, in theory, determine if T has a no arg constructor at compile time, since it knows what type it was instantiated with and if that type has such a constructor. – RHSeeger Apr 19 '11 at 02:24
  • @RHSeeger - the compiler can't even in theory, unless the method is visible only to the one compilation unit. If the bound is T extends List say, there is no fixed set of types that T can be, since the .class file may be used by code not compiled with the .java file. – sbridges Apr 19 '11 at 02:32
  • @sbridges - And, if you had "new T()" and you tried to instantiate it with a List, it would be able to say "Nope, can't do that, List doesn't support such a constructor" – RHSeeger Apr 19 '11 at 02:35
1

Yes, new T() is impossible as generic is a compile time feature in Java. During runtime the generic information is lost; therefore, you will not be able to do new T() since the JVM have no idea what T is during runtime.

You might be out of luck to use the exact syntax as you mentioned using Java.

Alvin
  • 10,308
  • 8
  • 37
  • 49
0

Thank you guys, in all, we cannot use it in JAVA. As Sbridges' way, in C#, we can implement like this:

static T Create(Type type)
{
    return (T)Activator.CreateInstance(type);
}

or even easier:

static T Create()
{
    return Activator.CreateInstance<T>();
}

Just let you know.

Howard
  • 3,638
  • 4
  • 32
  • 39