在通用Java中强制转换更好的解决方案 [英] better solution with cast in generic java

查看:79
本文介绍了在通用Java中强制转换更好的解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下代码:

  Object li = new Object(); 

//这会导致编译器警告

ArrayList< String> lo =(ArrayList< String>)(li);

好的,我编辑了这个问题,抱歉,我犯了一个错误,关键是,因为它当我们转换到目标是一个参数化类型的目标时,会产生编译时警告,有没有更好的解决方案,以便我可以防止代码导致编译时警告?



在处理数组时,我们使用Arrays.newInstance来替换使用cast。






原始问题的代码:

  // List< String>是ArrayList的超类

List< String> listOne = new List< String>();

ArrayList< String> listTwo =(List< String>)listOne;


解决方案

如果您遇到这种情况,选项。首先是做一个未经检查的强制转换:

  Object o = getObjectFromSomewhereMysterious(); 
列表< String> lst =(List< String>)o; //编译器警告

这会引起你提到的警告 - 这意味着,一个href =http://docs.oracle.com/javase/tutorial/java/generics/erasure.html =nofollow>类型擦除,
在运行时只能检查转换确保 o List ,但不是 List< String> 。例如,如果 o HashMap ,那么演员阵容将立即失败,但是如果它是列表< Integer> 它不会失败...直到某些以后,当您尝试将 lst 的元素视为字符串。这被称为污染堆


  //稍后放置在代码路径中 - 谁知道,它可能在数英里之外
String str = lst.get(0); // ClassCastException如果lst不是一个真正的List< String>

只要您确定转换是安全的,就可以禁止编译器警告:

  @SuppressWarnings(unchecked)//这是安全的,因为等于等于
List< String> lst =(List< String>)o;

总是记录警告可以被抑制的原因 - 这有助于保持代码可维护。



第二个选项是安全地使用它:

 列表与LT;?> lst =(List<> o; 

这意味着 lst 是一个 一些未知类型的列表。它允许你避免未经检查的强制转换,但限制你可以用 lst 做什么:

  lst.add(some string); //编译器错误

该语句是非法的,因为我们不知道 lst 可以容纳 String s。我们可以做的最好的是从中读取,但即使这样,元素也只能输入为 Object

  Object element = lst.get(0); 


Suppose I have the following code:

Object li = new Object(); 

// this causes a compiler warning   

ArrayList<String> lo = (ArrayList<String>)(li); 

Okay, I have edited the question, sorry, I made a mistake, the point is, since it will cause a compile time warning when we cast to the target, whose target is a parameterized type, is there any better solution so that I can prevent the code from causing a compile time warning?

When dealing with arrays, we have Arrays.newInstance to replace the use of cast.


code from original question:

// List<String> is a superclass of ArrayList

List<String>      listOne =  new List<String>();

ArrayList<String> listTwo = (List<String>) listOne; 

解决方案

If you are in such a situation, you have two options. The first is to do an unchecked cast:

Object o = getObjectFromSomewhereMysterious();
List<String> lst = (List<String>)o; //compiler warning

This will cause the warning you mention - what it means is that, because of type erasure, at runtime the cast can only check to make sure o is a List, but not a List<String>. So for example if o is a HashMap the cast will fail immediately, but if it's a List<Integer> it won't fail... until some later time when you try to treat an element of lst like a String. This is known as "polluting the heap":

//some later place in the code path - who knows, it could be miles away
String str = lst.get(0); //ClassCastException if lst isn't really a List<String>

As long as you can be sure that the cast is safe, you can suppress the compiler warning:

@SuppressWarnings("unchecked") //this is safe because blah blah blah
List<String> lst = (List<String>)o;

Always document why the warning can be suppressed - this helps to keep the code maintainable.

The second option is to play it safe:

List<?> lst = (List<?>)o;

This means lst is a List of some unknown type. It allows you to avoid the unchecked cast, but places restrictions on what you can do with lst:

lst.add("some string"); //compiler error

That statement is illegal since we don't know whether lst is allowed to hold Strings. The best we can do is read from it, but even then elements are only typed as Object:

Object element = lst.get(0);

这篇关于在通用Java中强制转换更好的解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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