当前位置: 首页 > 面试题库 >

如何正确使用泛型类型的数组?

谢昊乾
2023-03-14
问题内容

我有一个类,可以根据消息的类将传入的消息映射到匹配的读者。所有消息类型都实现接口消息。读者在mapper类中注册,说明它将能够处理的消息类型。这些信息需要以某种方式存储在消息阅读器中,而我的方法是private final从构造函数中设置一个数组。

现在,似乎我对泛型和/或数组有些误解,似乎无法弄清楚,请参见下面的代码。它是什么?

public class HttpGetMessageReader implements IMessageReader {
    // gives a warning because the type parameter is missing
    // also, I actually want to be more restrictive than that
    // 
    // private final Class[] _rgAccepted;

    // works here, but see below
    private final Class<? extends IMessage>[] _rgAccepted;

    public HttpGetMessageReader()
    {
        // works here, but see above
        // this._rgAccepted = new Class[1];

        // gives the error "Can't create a generic array of Class<? extends IMessage>"
        this._rgAccepted = new Class<? extends IMessage>[1];

        this._rgAccepted[0] = HttpGetMessage.class;
    }
}

ETA正如cletus正确指出的那样,最基本的谷歌搜索表明Java不允许通用数组。 对于给出的示例(例如E[] arr = new E[8],其中,E是周围类的类型参数),我绝对理解这一点。但是为什么new Class[n]允许?那么执行此操作的“适当”(或至少常见)方法是什么?


问题答案:

Java不允许通用数组。Java Generics
FAQ
中的更多信息。

要回答您的问题,只需使用List(可能是ArrayList)而不是数组。

可以在Java理论和实践中找到更多解释:泛型陷阱:

泛型不是协变的

尽管您可能会认为将集合视为数组的抽象很有帮助,但它们具有一些集合没有的特殊属性。Java语言中的数组是协变的-
这意味着,如果Integer扩展Number(它可以这样做),则不仅是Integer Number,而且a Integer[]也是a
Number[],您可以自由传递或分配Integer[]a
Number[],对于。(更正式,如果Number是的超类型Integer,则Number[]是一个超类型Integer[]。)你可能会认为,同样是通用的类型以及真正的-这List<Number>
是一个超List<Integer>,并且您可以通过一个List<Integer>
其中List<Number>的预期。不幸的是,它不能那样工作。

事实证明,这样做有一个很好的理由:这样做会破坏安全性泛型应该提供的类型。假设您可以将分配
List<Integer>List<Number>。然后,以下代码将使您可以将非的内容 Integer放入List<Integer>

List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

因为ln是a List<Number>,所以添加a
Float似乎是完全合法的。但是,如果ln用li别名,那么它将破坏li定义中隐含的类型安全保证-它是整数列表,这就是为什么泛型不能协变的原因。



 类似资料:
  • 我有一个数据库事务函数,可以进行多个查询,并以[resultQuery1、resultQuery2等格式返回每个查询的结果]。我不确定如何为这个泛型函数提供预期的返回类型。 游戏场 示例: 错误: 类型“(字符串|{id:number;})[]不可分配给类型“T”(字符串|{id:number;})[]”可分配给类型为“T”的约束,但“T”可以用约束“any[]”的不同子类型实例化。

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 问题内容: 我正在创建一个通用类,并且需要使用一种方法来了解当前使用的通用类型的Class。原因是我调用的方法之一期望将此作为参数。 例: 显然,上面的示例不起作用,并导致以下错误:类型参数T的非法类文字。 我的问题是:有人知道这方面有很好的选择或解决方法吗? 问题答案: 仍然存在相同的问题:常规信息在运行时被删除,无法恢复。一种解决方法是在静态方法的参数中传递T类: 很难看,但是可以用。

  • 考虑一个具有的API,如下所示: 很简单,只有页面大小和跳过计数属性。 此外,现在我还有一些类,它们也包含但未分页。 在我的测试中,我希望他们都能实现一个接口,这样我就可以用一些更基本的测试来生成一个通用的基本测试类。为此,我添加了我认为会起作用的内容: 我将PagedResults更改为: 错误 但现在编译器抱怨PagedResultBase继承的所有地方的使用情况(?)从。 但是,如果我将接口

  • 问题内容: 如何创建泛型类型的数组?通用方法如何工作?它返回通用数组的副本。因此可以创建通用数组。但是如何?怎么能写一个类似的方法呢? 问题答案: 如果需要在运行时创建它,则至少需要在此时知道类型,因此可以使用以下方法: where 是泛型类型,是的类,并且是初始大小。 这里的文件

  • 我试图实现一个接受泛型参数的函数定义,只要它扩展了另一个特定的泛型类型。简言之参数A必须扩展参数B,其中A和B都是泛型的。 下面是我的示例 用法示例如下 一些封闭的班级 和函数调用 我不想在抽象类声明中定义E,因为T已经在那里定义了。 我也试着做了以下几点: 将myList定义为接受扩展T的键 将E定义为T类型(无法找到如何指定它在函数中扩展T 但它从来都不起作用。有没有办法做到这一点?我在Sta