简体   繁体   English

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

[英]Java generic constructors syntax and purpose

Java constructors can be generic: http://docs.oracle.com/javase/tutorial/java/generics/methods.html Java构造函数可以是通用的: 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? 你能从JDK或你自己的例子中展示一个例子吗?

  2. Why statement like 为何如此陈述

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

is compiled without error even when class Integer doesn't have generic constructor? 即使类Integer没有泛型构造函数,编译时也没有错误?

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 不能用Java 7在Eclipse中编译。它抱怨道

The constructor Integer(int) of type Integer is not generic; Integer类型的构造函数Integer(int)不是通用的; it cannot be parameterized with arguments 它不能用参数参数化

In Java 8, this is allowed, although it still issues a warning: 在Java 8中,这是允许的,尽管它仍然会发出警告:

Unused type arguments for the non generic constructor Integer(int) of type Integer; 非泛型构造函数Integer(int)的未使用类型参数,类型为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) (如果这个差异是你真正感兴趣的,你可以考虑将其作为一个单独的问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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