简体   繁体   中英

Java generic constructors syntax and purpose

Java constructors can be generic: http://docs.oracle.com/javase/tutorial/java/generics/methods.html

However I can't find a good example of how to declare and invoke generic constructor. Moreover I don't understand the purpose of generic constructor as type parameter's scope is limited to constructor.

Having class with generic constructor:

public class MyClass {

    public <T> MyClass(T data) {
        // ...
    }

}

we invoke it as:

MyClass obj = new <Integer>MyClass(12);

So my questions are:

  1. What is the purpose of generic constructor? Can you show an example from JDK or your own example?

  2. Why statement like

     Integer val = new <String>Integer(100); 

is compiled without error even when class Integer doesn't have generic constructor?

One purpose of a generic constructor can be the same as for some generic methods: To make sure that several arguments refer to the same type.

Consider the following example (yes, it's a bit contrived, but should show the point) :

import java.util.ArrayList;
import java.util.Collection;

public class GenericConstructorTest 
{
    public static void main(String[] args)
    {
        Collection<String> strings = new ArrayList<String>();
        ClassWithParam c0 = new <String>ClassWithParam("String", strings);
    }
}

class ClassWithParam
{
    public <T> ClassWithParam(T data, Collection<T> collection) 
    {
        collection.add(data);
    }
}

It does not matter for the class or its constructor which type exactly is used there. It's only important to know that the collection that was given as the second argument can take elements of the type that was given as the first argument.

(I'd like to show a more realistic, practical example, but think that it's rather rarely necessary to parameterize a constructor this way, and one could even consider that this is just a "side effect" of the possibility to parameterize methods , and the fact that there is no reason to explicitly disallow this for constructors...)


EDIT As per request in the comment, and example where the given arguments are atually used . It's still rather contrived. More realistic examples could be structurally similar and refer to some sorts of listeners , but would involve much more code:

public class GenericConstructorTest 
{
    public static void main(String[] args)
    {
        Callback<String> callback = new Callback<String>();
        ClassWithParam c0 = new <String>ClassWithParam("String", callback);
        c0.execute();
    }
}

class ClassWithParam
{
    private Runnable runnable;

    public <T> ClassWithParam(final T data, final Callback<T> callback) 
    {
        runnable = new Runnable()
        {
            @Override
            public void run()
            {
                callback.call(data);
            }
        };
    }

    void execute()
    {
        runnable.run();
    }
}

class Callback<T>
{
    void call(T t)
    {
        System.out.println("Called with "+t);
    }
}

The second example that you posted

Integer val = new <String>Integer(100);

does not compile in Eclipse with Java 7. It complains

The constructor Integer(int) of type Integer is not generic; it cannot be parameterized with arguments

In Java 8, this is allowed, although it still issues a warning:

Unused type arguments for the non generic constructor Integer(int) of type Integer; it should not be parameterized with arguments

(If this difference is what you're actually interested in, you might consider asking this as a separate question)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM