如何在泛型类中强制对返回值进行类型定义?

huangapple go评论60阅读模式
英文:

How to force type on return value in a generic class?

问题

让我们假设我有一个通用类:

public final class MyClass<T> {
    private List<T> list;

    public MyClass() {

    }
}

两个问题:

我想强制用户创建一个与之匹配的通用返回类型,这就是为什么我创建了一个通用类,但显然他可以这样做:

MyClass item = new MyClass();

还可以这样做:

MyClass item = new MyClass<Customer>();

我想强制开发人员使用与提供的类型相同的类型来定义它们的返回类型,这样他们只能执行以下操作:

MyClass<Customer> item = new MyClass<Customer>();

该类的目的是在构造函数中获取一个类型,比如 Customer 类,并创建该类型的通用列表。但由于返回对象在应用程序层之间传递,我希望强制它具有 MyClass<Customer> 的签名,以便轻松理解它包含的列表类型。

英文:

Let's say I have a generic class:

public final  class MyClass&lt;T&gt; {
    private List&lt;T&gt; list;

    public MyClass(){

    }
}

Two questions:

I want to force the user to create a generic return type as well, this is why I created a generic class but apparently he can do this:

MyClass item = new MyClass();

and also this:

MyClass item = new MyClass&lt;Customer&gt;();

I want to force the developer to define their return type with the same type they supplied so they would only be able to do:

MyClass&lt;Customer&gt; item= new MyClass&lt;Customer&gt;();

The purpose of this class is to get a type in the constructor, let's say class Customer, and create a generic list of that type but since the return object is passed between the application layer I want to force it to have a signature MyClass&lt;Customer&gt; so its easy to understand the type of list it contains.

答案1

得分: 1

如评论中已经提到的,出于向后兼容性的原因,泛型并不是强制的。

如果您将类型类作为构造函数参数请求,您的开发人员将必须考虑一个类型:

private static class MyClass&lt;T&gt; {
    private List&lt;T&gt; list;

    public MyClass(Class&lt;T&gt; clazz){

    }
}

public static void main(String args[])
{
	MyClass myclass=new MyClass(Object.class);
}

但正如您所见,他们始终可以传递 Object 如何在泛型类中强制对返回值进行类型定义?

英文:

As already mentioned in the comments, for backwards compatibility reasons generics are not forced.

If you ask the type class as constructor parameter your developers will have to think of a type:

private static class MyClass&lt;T&gt; {
    private List&lt;T&gt; list;

    public MyClass(Class&lt;T&gt; clazz){

    }
}

public static void main(String args[])
{
	MyClass myclass=new MyClass(Object.class);
}

But as you can see, they can always pass Object 如何在泛型类中强制对返回值进行类型定义?

答案2

得分: 1

这个类的目的是在构造函数中获取一种类型,假设是类"Customer",并创建该类型的通用列表...

不,作为MyClass的开发者,你不需要这样做。您可以在代码中安全地执行类似以下的操作(与调用者是否使用原始MyClass类型无关):

public final class MyClass<T> {
    private List<T> list;

    public MyClass(){
        this.list = new ArrayList<>();
    }
}

除了Java出于良好(且实用)原因允许这样做之外,您的类型参数没有受限制只是表明您自己也不太关心(当在使用MyClass而不是MyClass<Something>时,Java默认使用Object)。

然而,如果您寻求的是基于类型的动态行为,例如动态实例化元素,则最好是从调用者那里获取类实例本身:

public final class MyClass<T> {
    private Class<T> type;
    private List<T> list;

    public MyClass(Class<T> type){
        this.type = type;
        this.list = new ArrayList<>();
    }

    // 然后使用type对元素类型执行动态行为
}

这将迫使调用者发送一个类型,因此对于他们使用原始类型几乎是无意义的。但是您也应该有理由这样做。

英文:

> The purpose of this class is to get a type in the constructor, let's say class Customer, and create a generic list of that type...

No, you don't need this as the developer of MyClass. You can safely do something like this in your code (and it has nothing to do with whether the caller will use the raw MyClass type):

public final  class MyClass&lt;T&gt; {
    private List&lt;T&gt; list;

    public MyClass(){
    	this.list = new ArrayList&lt;&gt;();
    }
}

Beside the fact that Java allows this for good (and practical) reasons, your type parameter being unbounded simply suggests that you yourself don't care much either (Java uses Object by default when MyClass is used instead of MyClass&lt;Something&gt;).

If, however, what you're looking for is dynamic behavior based on the type, like instantiating elements dynamically, then the best is to take the class instance itself from your caller:

public final  class MyClass&lt;T&gt; {
	private Class&lt;T&gt; type;
    private List&lt;T&gt; list;

    public MyClass(Class&lt;T&gt; type){
    	this.type = type;
    	this.list = new ArrayList&lt;&gt;();
    }

    //then use type to perform your dynamic behavior on the element type
}

This will force your callers to send a type, therefore making it almost pointless for them to use the raw type. But you should have a reason to do this too.

huangapple
  • 本文由 发表于 2020年9月1日 22:40:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63689915.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定