这是通用的自动装箱吗?

时间:2010-07-10 16:08:51

标签: java generics autoboxing

在不使用常用符号的情况下分配值,例如“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);
}

在过去,只有方法上的返回对象和接收类型的简单强制转换就足够了,因此在接收器对象上缺少通用符号,它更加相似和快速写入,对此的任何其他提示?

2 个答案:

答案 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

相关问题

另见

  • Effective Java 2nd Edition,Item 24:Elimate unchecked warnings

在Typesafe异构容器

也许你想要像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是相反的转换。所述问题与自动装箱无关。

另见

相关问题

答案 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 )。