首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java泛型和类型转换

Java泛型和类型转换
EN

Stack Overflow用户
提问于 2013-04-20 17:09:13
回答 6查看 935关注 0票数 19

我有一个错误创建的容器对象,它将不同java类型(字符串、布尔值等)的值保存在一起。

代码语言:javascript
复制
public class BadlyCreatedClass {
    public Object get(String property) {
        ...;
    }
};

我们以这种方式从其中提取值

代码语言:javascript
复制
String myStr = (String) badlyCreatedObj.get("abc");
Date myDate = (Date) badlyCreatedObj.get("def");

我不得不用这个对象写一些新的代码,我想看看有没有干净的方法来做到这一点。更具体地说,下面哪种方法是首选的?

显式转换

代码语言:javascript
复制
String myStr = (String) badlyCreatedObj.get("abc")
Date myDate = (Date) badlyCreatedObj.get("def");

使用通用cast的

代码语言:javascript
复制
public <X> X genericGet(String property) {

}

public String getString(String property) { 
return genericGet(property); 
}

public Date getDate(String property) { 
return genericGet(property); 
}

使用Class.cast

代码语言:javascript
复制
<T> T get(String property, Class<T> cls) {
    ;
}

我已经在SO Java generic function: how to return Generic type上看了几个相关的问题,他们似乎都说这样的类型转换是危险的,ALthough我看不出三者之间有太大的区别,考虑到这一点,你更喜欢哪种方法?

谢谢

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-04-20 17:18:59

为了给出一个快速的答案,而不是深入讨论良好的编程实践...

我将使用:

代码语言:javascript
复制
private <X> X genericGet(String property) {

}

public String getString(String property) { 
//... checks on property (String specific)...
Object obj = genericGet(property);
//... checks if obj is what is expected and if good return it
return obj; 
}

public Date getDate(String property) { 
//... checks on property (Date specific)...
Object obj = genericGet(property);
//... checks if obj is what is expected and if good return it
return obj
}

向私有genericGet发出通知。这样,我就可以检查get属性是否是我等待接收的东西,并以正确的方式处理它。

我可以根据属性在getString依赖中添加检查,以确保答案将是String对象。

我可以对属性中的getDate做其他检查,以确保它将是将返回的日期。

等等。

票数 3
EN

Stack Overflow用户

发布于 2013-04-20 17:25:08

就我个人而言,将许多不同的对象放在一个地方,然后检查您想要返回的内容似乎有点错误。也许你可以将持有者存储在那个BadlyCreatedClass中。

类似于:

代码语言:javascript
复制
class Holder {
    private long id;
    private String name;
    private Date dateofBirth;

    //getters and setters
}

然后根据id进行检索,因此不需要强制转换。

你也可以告诉我们你想做什么。

票数 3
EN

Stack Overflow用户

发布于 2013-04-20 19:16:41

泛型强制转换方法会导致编译器发出未经检查的警告。未经检查的警告表明,在运行时没有(完全)检查强制转换,即,即使值不是正确的类型,它也可能成功。这可能导致变量保存的值与其声明的类型不兼容,这种情况被Java Language Specification称为heap pollution

下面的程序演示了这一点:

代码语言:javascript
复制
class Holder {
    Object value;

    Holder(Object value) {
        this.value = value;
    }

    <T> T get() {
        return (T) value;
    }
}

class C<T> {
    T value;

    C(Holder h) {
        value = h.get();
    }
}

public class Test {
    public static void main(String [] args) throws IOException {
        Holder holder = new Holder("Hello");
        C<Integer> c = new C<Integer>(holder);
        System.out.println("I just put a String into a variable of type Integer");

        // much later, possibly in a different part of your program
        c.value.longValue(); // throws ClassCastException
    }
}

因此,我强烈建议使用检查类型转换。检查普通类型转换(第一种方法)和反射类型转换(第三种方法)。但是,反射强制转换不适用于参数化类型(List<String>.class无法编译...)。

因此,最简单和最灵活的安全解决方案是普通的强制转换。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16118578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档