use*_*313 88 java generics casting
这不编译,任何建议表示赞赏.
...
List<Object> list = getList();
return (List<Customer>) list;
Run Code Online (Sandbox Code Playgroud)
编译器说:不能投List<Object>给List<Customer>
irr*_*ble 142
您始终可以将任何对象转换为任何类型,方法是先将其向上转换为Object.在你的情况下:
(List<Customer>)(Object)list;
Run Code Online (Sandbox Code Playgroud)
您必须确保在运行时列表中只包含Customer对象.
批评者说,这样的演员表明你的代码有问题; 你应该能够调整你的类型声明以避免它.但Java泛型太复杂了,并不完美.有时您只是不知道是否有一个非常好的解决方案来满足编译器,即使您非常了解运行时类型并且您知道您尝试做什么是安全的.在这种情况下,只需根据需要进行原油铸造,这样就可以将工作留在家中.
Bri*_*new 36
这是因为虽然客户是对象,但客户列表不是对象列表.如果是,那么您可以将任何对象放在客户列表中.
Boz*_*zho 32
根据您的其他代码,最佳答案可能会有所不同.尝试:
List<? extends Object> list = getList();
return (List<Customer>) list;
Run Code Online (Sandbox Code Playgroud)
要么
List list = getList();
return (List<Customer>) list;
Run Code Online (Sandbox Code Playgroud)
但请记住,不建议不要进行此类未经检查的演员表.
Pet*_*rey 21
你可以使用双重演员.
return (List<Customer>) (List) getList();
Run Code Online (Sandbox Code Playgroud)
rou*_*dar 17
使用Java 8 Streams:
有时蛮力铸造很好:
List<MyClass> mythings = (List<MyClass>) (Object) objects
Run Code Online (Sandbox Code Playgroud)
但这是一个更通用的解决方案:
List<Object> objects = Arrays.asList("String1", "String2");
List<String> strings = objects.stream()
.map(element->(String) element)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
有很多好处,但有一个是如果你不能确定它包含什么,你可以更优雅地投射你的列表:
objects.stream()
.filter(element->element instanceof String)
.map(element->(String)element)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
d0x*_*d0x 11
另一种方法是使用 java 8 流。
List<Customer> customer = myObjects.stream()
.filter(Customer.class::isInstance)
.map(Customer.class::cast)
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
请注意,我不是java程序员,但在.NET和C#中,此功能称为逆变或协方差.我还没有深入研究过这些东西,因为它们是.NET 4.0中的新功能,我没有使用它,因为它只是测试版,所以我不知道这两个术语中的哪一个描述了你的问题,但让我描述一下技术问题.
我们假设你被允许演员.请注意,我说是演员,因为这就是你所说的,但有两种操作是可能的,即投射和转换.
转换意味着你得到一个新的列表对象,但是你说要转换,这意味着你想暂时将一个对象视为另一种类型.
这是问题所在.
如果允许以下内容会发生什么(注意,我假设在强制转换之前,对象列表实际上只包含Customer对象,否则即使在这个假设的java版本中,强制转换也不会起作用):
List<Object> list = getList();
List<Customer> customers = (List<Customer>)list;
list.Insert(0, new someOtherObjectNotACustomer());
Customer c = customers[0];
Run Code Online (Sandbox Code Playgroud)
在这种情况下,这将尝试将对象(不是客户)视为客户,并且您将在列表内部或从分配中的某一点获得运行时错误.
然而,泛型应该为你提供类型安全的数据类型,比如集合,并且因为他们喜欢抛出"保证"这个词,所以不允许使用这种类型的演员,以及随后出现的问题.
在.NET 4.0中(我知道,你的问题是关于java),这将在一些非常特殊的情况下被允许,编译器可以保证你所做的操作是安全的,但在一般意义上,这种类型的强制转换不会被)允许.这同样适用于java,虽然我不确定是否有任何计划引入java语言的共同和逆转.
希望有比我更好的Java知识的人可以告诉你java未来或实现的具体细节.
| 归档时间: |
|
| 查看次数: |
172588 次 |
| 最近记录: |