Java 如何将 List<Object> 转换为 List<MyClass>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1917844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:24:30  来源:igfitidea点击:

How to cast List<Object> to List<MyClass>

javagenericscasting

提问by user198313

This does not compile, any suggestion appreciated.

这不会编译,任何建议表示赞赏。

 ...
  List<Object> list = getList();
  return (List<Customer>) list;

Compiler says: cannot cast List<Object>to List<Customer>

编译器说:无法List<Object>转换为List<Customer>

回答by Brian Agnew

That's because although a Customer is anObject, a List of Customers is not aList of Objects. If it was, then you could put anyobject in a list of Customers.

那是因为尽管客户是一个对象,但客户列表不是对象列表。如果是,那么您可以将任何对象放入客户列表中。

回答by vrm

You should just iterate over the list and cast all Objects one by one

您应该遍历列表并一个一个地投射所有对象

回答by Aric TenEyck

Your best bet is to create a new List<Customer>, iterate through the List<Object>, add each item to the new list, and return that.

最好的办法是创建一个 new List<Customer>,遍历List<Object>,将每个项目添加到新列表中,然后返回它。

回答by Bozho

Depending on your other code the best answer may vary. Try:

根据您的其他代码,最佳答案可能会有所不同。尝试:

List<? extends Object> list = getList();
return (List<Customer>) list;

or

或者

List list = getList();
return (List<Customer>) list;

But have in mind it is not recommended to do such unchecked casts.

但请记住,不建议进行此类未经检查的强制转换。

回答by Lasse V. Karlsen

Note that I am no java programmer, but in .NET and C#, this feature is called contravariance or covariance. I haven't delved into those things yet, since they are new in .NET 4.0, which I'm not using since it's only beta, so I don't know which of the two terms describe your problem, but let me describe the technical issue with this.

请注意,我不是 Java 程序员,但在 .NET 和 C# 中,此功能称为逆变或协变。我还没有深入研究这些东西,因为它们是 .NET 4.0 中的新东西,我没有使用它,因为它只是测试版,所以我不知道这两个术语中的哪一个描述了您的问题,但让我描述一下技术问题。

Let's assume you were allowed to cast. Note, I say cast, since that's what you said, but there are two operations that could be possible, castingand converting.

假设您被允许进行投射。请注意,我说的是cast,因为这就是您所说的,但是有两种可能的操作,castconvert

Converting would mean that you get a new list object, but you say casting, which means you want to temporarily treat one object as another type.

转换意味着您获得一个新的列表对象,但您说的是强制转换,这意味着您想暂时将一个对象视为另一种类型。

Here's the problem with that.

这就是问题所在。

What would happen if the following was allowed (note, I'm assuming that before the cast, the list of objects actually only contain Customer objects, otherwise the cast wouldn't work even in this hypothetical version of java):

如果允许以下情况会发生什么(注意,我假设在转换之前,对象列表实际上只包含 Customer 对象,否则即使在这个假设的 java 版本中,转换也无法工作):

List<Object> list = getList();
List<Customer> customers = (List<Customer>)list;
list.Insert(0, new someOtherObjectNotACustomer());
Customer c = customers[0];

In this case, this would attempt to treat an object, that isn't a customer, as a customer, and you would get a runtime error at one point, either form inside the list, or from the assignment.

在这种情况下,这将尝试将不是客户的对象视为客户,并且您会在某一时刻收到运行时错误,无论是在列表中的形式还是从分配中。

Generics, however, is supposed to give you type-safe data types, like collections, and since they like to throw the word 'guaranteed' around, this sort of cast, with the problems that follow, is not allowed.

然而,泛型应该为您提供类型安全的数据类型,例如集合,并且由于它们喜欢抛出“保证”这个词,因此这种类型的转换以及随之而来的问题是不允许的。

In .NET 4.0 (I know, your question was about java), this will be allowed in some very specific cases, where the compiler can guarantee that the operations you do are safe, but in the general sense, this type of cast will not be allowed. The same holds for java, although I'm unsure about any plans to introduce co- and contravariance to the java language.

在 .NET 4.0 中(我知道,你的问题是关于 java),这在一些非常特殊的情况下是允许的编译器可以保证你所做的操作是安全的,但在一般意义上,这种类型的转换不会被)允许。Java 也是如此,尽管我不确定是否有任何计划将协变和逆变引入 Java 语言。

Hopefully, someone with better java knowledge than me can tell you the specifics for the java future or implementation.

希望有比我更好的 Java 知识的人可以告诉您 Java 未来或实现的细节。

回答by Rob Sobers

You can't because List<Object>and List<Customer>are not in the same inheritance tree.

你不能因为List<Object>List<Customer>不在同一个继承树中。

You could add a new constructor to your List<Customer>class that takes a List<Object>and then iterate through the list casting each Objectto a Customerand adding it to your collection. Be aware that an invalid cast exception can occur if the caller's List<Object>contains something that isn't a Customer.

您可以向您的List<Customer>类添加一个新的构造函数,该构造函数采用 a List<Object>,然后遍历列表,将每个构造函数强制转换Object为 aCustomer并将其添加到您的集合中。请注意,如果调用方List<Object>包含不是Customer.

The point of generic lists is to constrain them to certain types. You're trying to take a list that can have anythingin it (Orders, Products, etc.) and squeeze it into a list that can only take Customers.

泛型列表的重点是将它们限制为某些类型。您正在尝试获取一个可以包含任何内容(订单、产品等)的列表,并将其压缩到一个只能包含客户的列表中。

回答by irreputable

you can always cast any object to any type by up-casting it to Object first. in your case:

您始终可以通过先将任何对象向上转换为 Object 来将其转换为任何类型。在你的情况下:

(List<Customer>)(Object)list; 

you must be sure that at runtime the list contains nothing but Customer objects.

您必须确保在运行时列表只包含 Customer 对象。

Critics say that such casting indicates something wrong with your code; you should be able to tweak your type declarations to avoid it. But Java generics is too complicated, and it is not perfect. Sometimes you just don't know if there is a pretty solution to satisfy the compiler, even though you know very well the runtime types and you know what you are trying to do is safe. In that case, just do the crude casting as needed, so you can leave work for home.

批评者说这样的转换表明你的代码有问题;您应该能够调整您的类型声明以避免它。但是Java泛型太复杂了,还不够完美。有时你只是不知道是否有一个很好的解决方案来满足编译器,即使你非常了解运行时类型并且你知道你正在尝试做什么是安全的。在这种情况下,只需根据需要进行粗铸,这样您就可以将工作留在家中。

回答by nd.

As others have pointed out, you cannot savely cast them, since a List<Object>isn't a List<Customer>. What you could do, is to define a view on the list that does in-place type checking. Using Google Collectionsthat would be:

正如其他人指出的那样,你不能安全地投射它们,因为 aList<Object>不是 a List<Customer>。您可以做的是在列表上定义一个进行就地类型检查的视图。使用Google Collections将是:

return Lists.transform(list, new Function<Object, Customer>() {
  public Customer apply(Object from) {
    if (from instanceof Customer) {
      return (Customer)from;
    }
    return null; // or throw an exception, or do something else that makes sense.
  }
});

回答by Hendra Jaya

Similar with Bozho above. You can do some workaround here (although i myself don't like it) through this method :

类似于上面的Bozho。你可以通过这个方法在这里做一些解决方法(虽然我自己不喜欢它):

public <T> List<T> convert(List list, T t){
    return list;
}

Yes. It will cast your list into your demanded generic type.

是的。它会将您的列表转换为您所需的通用类型。

In the given case above, you can do some code like this :

在上面给定的情况下,您可以执行以下代码:

    List<Object> list = getList();
    return convert(list, new Customer());

回答by Peter Lawrey

You can use a double cast.

您可以使用双重演员。

return (List<Customer>) (List) getList();