3

不使用“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);
}

在过去,仅方法上的返回对象和接收类型上的简单强制转换就足够了,因此由于接收器对象上缺乏通用符号,因此编写起来更加相似和快速,还有其他提示吗?

4

2 回答 2

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 第 2 版,第 24 条:消除未经检查的警告

关于类型安全的异构容器

也许您想要 Josh Bloch 所说的 Typesafe Heterogeneous Container 之类的东西。这是 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);编译(这是一件好事!)。

也可以看看


关于自动装箱

自动装箱是从原始int类型到引用类型的隐式转换Integer;自动拆箱是相反的转换。所述问题与自动装箱无关。

也可以看看

相关问题

于 2010-07-10T16:22:48.160 回答
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 代表 int,Double 代表 double)。

于 2010-07-19T08:27:28.037 回答