Java泛型构造函数的语法和目的

时间:2014-10-04 14:29:44

标签: java generics

Java构造函数可以是通用的:http://docs.oracle.com/javase/tutorial/java/generics/methods.html

但是我找不到如何声明和调用泛型构造函数的好例子。此外,我不理解泛型构造函数的目的,因为类型参数的作用域仅限于构造函数。

使用泛型构造函数的类:

public class MyClass {

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

}

我们将其调用为:

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

所以我的问题是:

  1. 通用构造函数的用途是什么?你能从JDK或你自己的例子中展示一个例子吗?

  2. 为什么声明像

    Integer val = new <String>Integer(100);
    
  3. 即使类Integer没有泛型构造函数,

    编译时也没有错误?

1 个答案:

答案 0 :(得分:6)

泛型构造函数的一个目的可以与某些泛型方法相同:确保多个参数引用相同的类型。

考虑下面的例子(是的,它有点人为,但应该说明一点):

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);
    }
}

对于类或其构造函数来说无关紧要在那里使用类型。重要的是要知道作为第二个参数给出的集合可以采用作为第一个参数给出的类型的元素。

(我想展示一个更现实,更实用的例子,但是认为很少有必要以这种方式参数化构造函数,甚至可以认为这只是参数化的一个“副作用” 方法,以及没有理由为构造函数明确禁止这一事实......)


编辑根据评论中的请求,以及给定参数通常使用的示例。它仍然相当做作。更现实的示例可能在结构上相似并且引用某些侦听器,但会涉及更多代码:

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);
    }
}

您发布的第二个示例

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

在Eclipse 7中没有使用Java 7进行编译。它抱怨

  

Integer类型的构造函数Integer(int)不是通用的;它不能用参数

参数化

在Java 8中,这是允许的,尽管它仍然会发出警告:

  

Integer类型的非泛型构造函数Integer(int)的未使用类型参数;它不应该用参数

参数化

(如果这个差异是你真正感兴趣的,你可以考虑将其作为一个单独的问题)