Eclipse正在向我发出以下形式的警告:
类型安全:从Object到HashMap的未选中转换
这是来自对我无法控制的API的调用返回Object:
HashMap<String, String> getItems(javax.servlet.http.HttpSession session) {
HashMap<String, String> theHash = (HashMap<String, String>)session.getAttribute("attributeKey");
return theHash;
}
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我想避免Eclipse警告,因为理论上它们至少表明存在潜在的代码问题.但是,我还没有找到一种消除这种方法的好方法.我可以将涉及的单行提取到方法中并添加@SuppressWarnings("unchecked")到该方法,从而限制了我忽略警告的代码块的影响.有更好的选择吗?我不想在Eclipse中关闭这些警告.
在我来到代码之前,它更简单,但仍然引发了警告:
HashMap getItems(javax.servlet.http.HttpSession session) {
HashMap theHash = (HashMap)session.getAttribute("attributeKey");
return theHash;
}
Run Code Online (Sandbox Code Playgroud)
当您尝试使用哈希时,问题出在其他地方,您会收到警告:
HashMap items = getItems(session);
items.put("this", "that");
Type safety: The method put(Object, Object) belongs to the raw type HashMap. References to generic type HashMap<K,V> should be parameterized.
Run Code Online (Sandbox Code Playgroud) 考虑这个例子(典型的OOP书籍):
我有一个Animal班级,每个人都Animal可以有很多朋友.
和子类一样Dog,Duck,Mouse等它添加特定的行为一样bark(),quack()等等.
这是Animal班级:
public class Animal {
private Map<String,Animal> friends = new HashMap<>();
public void addFriend(String name, Animal animal){
friends.put(name,animal);
}
public Animal callFriend(String name){
return friends.get(name);
}
}
Run Code Online (Sandbox Code Playgroud)
这里有一些代码片段有很多类型转换:
Mouse jerry = new Mouse();
jerry.addFriend("spike", new Dog());
jerry.addFriend("quacker", new Duck());
((Dog) jerry.callFriend("spike")).bark();
((Duck) jerry.callFriend("quacker")).quack();
Run Code Online (Sandbox Code Playgroud)
有什么办法可以使用泛型来返回类型来摆脱类型转换,这样我就可以说了
jerry.callFriend("spike").bark();
jerry.callFriend("quacker").quack();
Run Code Online (Sandbox Code Playgroud)
这里有一些返回类型的初始代码作为一个从未使用过的参数传递给方法.
public<T extends Animal> T callFriend(String name, T unusedTypeObj){
return (T)friends.get(name);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在运行时找出返回类型而不使用额外的参数instanceof?或者至少通过传递类型的类而不是虚拟实例. …
是否可以在Java中创建泛型类型的实例?我正在考虑基于我所看到的答案是no(由于类型擦除),但如果有人能看到我缺少的东西,我会感兴趣:
class SomeContainer<E>
{
E createContents()
{
return what???
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:事实证明,超级类型标记可用于解决我的问题,但它需要大量基于反射的代码,如下面的一些答案所示.
我会把这个开放一段时间,看看是否有人提出了与Ian Robertson的Artima文章截然不同的任何东西.
我在C#中有一个通用的对象列表,并希望克隆列表.列表中的项目是可复制的,但似乎没有选项可做list.Clone().
有一个简单的方法吗?
我有一个通用的方法与这个(虚拟)代码(是的我知道IList有谓词,但我的代码不使用IList但其他一些集合,无论如何这与问题无关...)
static T FindThing<T>(IList collection, int id) where T : IThing, new()
{
foreach T thing in collecion
{
if (thing.Id == id)
return thing;
}
return null; // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead.
}
Run Code Online (Sandbox Code Playgroud)
这给了我一个构建错误
"无法将null转换为类型参数'T',因为它可能是值类型.请考虑使用'default(T)'."
我可以避免这个错误吗?
这会导致编译时异常:
public sealed class ValidatesAttribute<T> : Attribute
{
}
[Validates<string>]
public static class StringValidation
{
}
Run Code Online (Sandbox Code Playgroud)
我意识到C#不支持通用属性.然而,经过大量的谷歌搜索,我似乎无法找到原因.
有谁知道为什么泛型类型无法衍生出来Attribute?任何理论?
任何人都可以向我解释为什么我想在C#中使用IList而不是List?
相关问题:为什么暴露它被认为是不好的List<T>
我怎样才能做到这一点?
public class GenericClass<T>
{
public Type getMyType()
{
//How do I return the type of T?
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我尝试的所有东西总是返回类型Object而不是使用的特定类型.
java 7中的菱形运算符允许以下代码:
List<String> list = new LinkedList<>();
Run Code Online (Sandbox Code Playgroud)
但是在Java 5/6中,我可以简单地写:
List<String> list = new LinkedList();
Run Code Online (Sandbox Code Playgroud)
我对类型擦除的理解是这些完全相同.(无论如何,通用都会在运行时删除).
为什么要钻石头呢?它允许哪些新功能/类型安全?如果它没有产生任何新功能,为什么他们将其作为功能提及?我对这个概念的理解是否有缺陷?
generics ×10
c# ×5
java ×5
list ×3
clone ×1
duplicates ×1
java-7 ×1
reflection ×1
return-value ×1
warnings ×1