在不使用常用符号的情况下分配值,例如“this。< Double> getAnything(int flag)”
private <T> T getAnything(int flag) {
Object o = null;
if (flag==0)
o=new String("NewString");
else if (flag==1)
o=new Double(0D);
return (T)o;
}
private void someMethod() {
String s = getAnything(0);
Double d = getAnything(1);
}
在过去,只有方法上的返回对象和接收类型的简单强制转换就足够了,因此在接收器对象上缺少通用符号,它更加相似和快速写入,对此的任何其他提示?
答案 0 :(得分:5)
目前还不清楚你要做的是什么,但应该指出的是,你的代码中没有任何类型的安全性。
Double d = getAnything(0);
// compiles fine, but throws ClassCastException at run time
这首先打败了使用泛型的目的。
当你写下这句话时,你引入了这种不自然的行为:
return (T)o; // warning: Type safety: Unchecked cast from Object to T
SuppressWarnings (“unchecked”)
in Java? 也许你想要像Josh Bloch所说的Typesafe异构容器。以下是Neal Gafter博客的引用:
这是一个简单但完整的API示例,它使用了类型令牌 THC模式,来自Josh的2006 JavaOne演讲:
public class Favorites { private Map<Class<?>, Object> favorites = new HashMap<Class<?>, Object>(); public <T> void setFavorite(Class<T> klass, T thing) { favorites.put(klass, thing); } public <T> T getFavorite(Class<T> klass) { return klass.cast(favorites.get(klass)); } public static void main(String[] args) { Favorites f = new Favorites(); f.setFavorite(String.class, "Java"); f.setFavorite(Integer.class, 0xcafebabe); String s = f.getFavorite(String.class); int i = f.getFavorite(Integer.class); } }
使用这种模式可以获得类型安全性; int i = f.getFavorite(String.class);
NOT 编译(这是一件好事!)。
自动装箱是从原始int
到引用类型Integer
的隐式转换; autounboxing是相反的转换。所述问题与自动装箱无关。
int num = Integer.getInteger(“123”)
throw NullPointerException
? int
and an Integer
in Java/C#? boolean
? new Integer(i) == i
in Java?(是!!!)答案 1 :(得分:1)
我认为你将自动装箱与类型推断混为一谈。
类型推断是指编译器可以根据调用方法时使用的变量,告诉它应该在泛型方法上使用哪种类型。
例如,如果您有以下方法:
public <T extends SomeClass> T process(T obj) {
// call some methods of SomeClass on obj to process it here
return obj;
}
然后将其称为:
SomeChildClass a = new SomeChildClass(); // SomeChildClass extends SomeClass
a = process(a);
推断类型将是SomeChildClass;
可以从参数或返回类型推断出类型,如示例所示。但是编译器应该使用哪种类型并不总是显而易见的。如果发生这种情况,您可以使用您描述的方法this.<Double>getAnything(int flag)
强制执行该类型。这通常发生在以下情况:
public <T> List<T> getSomeList() {
// implementation
}
public void processList(List<SomeClass> list) {
// implementation
}
并致电
processList(getSomeList()); // compiler error: cannot convert List<Object> to List<SomeClass>
在这种情况下,您可能需要强制输入类型参数。
所有这一切,请考虑polygenelubricants所说的一切,因为他对你的代码提出了一些非常好的观点,并解释了什么是自动装箱(它与原始的包装类有关,比如Integer for int,Double for double for double )。