Java - 如何处理构造函数中的类型擦除? [英] Java -- How to deal with type erasure in constructors?

查看:119
本文介绍了Java - 如何处理构造函数中的类型擦除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的课程中有两个构造函数:

Let's say I have two constructors in my class:

public User (List<Source1> source){
...
}

public User (List<Source2> source) {
...
}

假设这两个构造函数都提供了有关用户的相同信息,并且是为不同用例构建用户的同等有效方法。

Let's say that both of these constructors provide the same information about a User and are equally valid ways to construct a user for different use cases.

在Java中,由于类型擦除,你不能这样做 - Java不会接受两个具有参数List<的构造函数。 ? >。

In Java, you can't do this because of type erasure -- Java won't accept two constructors that have as parameters List< ? >.

那么,解决这个问题的方法是什么?什么是不是矫枉过正但仍然尊重基本OO的解决方案?由于Java没有强大的泛型支持,因此必须构建一个工厂方法或其他接口似乎是错误的。

So, what is the way to get around this? What is a solution that is not overkill but still respects basic OO? It seems wrong to have to construct a factory method or other interface around this just because Java doesn't have strong generics support.

以下是我能想到的可能性:

Here are the possibilities I can think of:

1)接受列表<?> 作为构造函数的参数并在构造函数中解析哪种类型您需要的逻辑,或者如果它不是任何可接受的类型则抛出异常。

1) Accept a List<?> as a parameter for the constructor and parse in the constructor which kind of logic you need, or throw an exception if it's not any of the accepted types.

2)创建一个接受List的类,构造相应的User对象,以及返回它。

2) Create a class that accepts either List, constructs the appropriate User object, and returns it.

3)围绕 List< Source1> List< Source2>创建包装器; 可以传递给User构造函数。

3) Create wrappers around List<Source1> and List<Source2> that can be passed to the User constructor instead.

4)这个人有两个类的子类,其中所有的功能都是继承的,除了对于构造函数。一个构造函数接受Source1,另一个接受Source2。

4) Subclass this guy with two classes, where all of the functionality is inherited except for the constructor. The constructor of one accepts Source1, the other accepts Source2.

5)用一个构建器包装这个人,其中两个不同的构建器方法用于两个不同的数据源以进行实例化。

5) Wrap this guy with a builder where are two different builder methods for the two different sources of data for instantiation.

我的问题是这些:

1)是否需要使用Java进行此漏洞,或者有意的设计决定?什么是直觉?

1) Is the need to do this a flaw with Java, or an intentional design decision? What is the intuition?

2)在保持良好代码而不引入不必要的复杂性方面,哪种解决方案最强?为什么?

2) Which solution is strongest in terms of maintaining good code without introducing unneeded complexity? Why?

这个问题类似:在Java中围绕类型擦除设计构造函数但没有详细说明,它只是建议了各种解决方法。

This question is similar: Designing constructors around type erasure in Java but does not go into specifics, it just suggests various work-arounds.

推荐答案

通常的方法是使用工厂方法

public static User createFromSource1(List<Source1> source) {
    User user = new User();
    // build your User object knowing you have Source1 data
    return user;
}

public static User createFromSource2(List<Source2> source) {
    User user = new User();
    // build your User object knowing you have Source2 data
    return user;
}

如果想要使用<$ c进行构建$ c> Source1 或 Source2 (即你没有默认的构造函数),你只需隐藏你的构造函数,强迫客户使用你的工厂方法:

If you only want construction using Source1 or Source2 (ie you don't have a default constructor), you simply hide your constructor, forcing clients to use your factory methods:

private User () {
    // Hide the constructor
}

出现这个问题是因为你不能用不同的方式命名构造函数,如果这些是正常的方法,你将如何克服这个问题。因为构造函数名称被固定为类名,所以此代码模式只能区分,然后给出相同类型的擦除。

This problem arises because you can't name constructors differently, which would be how you'd overcome this if these were normal methods. Because constructor names are fixed as the class name, this code pattern is only way to distinguish then give the same type erasure.

这篇关于Java - 如何处理构造函数中的类型擦除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆