如何在java中隐式或自动转换

时间:2013-02-23 15:37:16

标签: java casting

我在“自动”投射属性时遇到了一些麻烦。

public abstract class MyType<T> {
    public abstract T getValue(String content);
}

public class MyString extends MyType<String> {
    @Override
    public String getValue(String content) {
        return String.valueOf(content);
    }
}

public class MyInteger extends MyType<Integer> {
    @Override
    public Integer getValue(String content) {
        return Integer.valueOf(content);
    }
}

public class User {
    private String _name;
    private int _id;

    public void setName(String name) {
        _name = name;
    }

    public String getName() {
        return _name;
    }

    public void setId(int id) {
        _id = id;
    }

    public int getId() {
        return _id;
    }
}

public class MainTest {
    public static void main(String[] args) {
        ArrayList<MyType> myTypes = new ArrayList<MyType>();
        myTypes.add(new MyString());
        myTypes.add(new MyInteger());

        User user = new User();

        for (MyType myType : myTypes) {
            try {
                user.setName((String) myType.getValue("foobar")); // getValue always returns an Object that I have to parse
                user.setId((Integer) myType.getValue("42")); // getValue always returns an Object that I have to parse
            } catch (Exception e) {
            }
        }
    }
}

请记住,这只是我问题的一个抽象例子。

如何更换铸件?我需要这样的东西:

user.setName((user.getName().getClass()) myType.getValue("foobar"));

不幸的是,eclipse告诉我这是错误的The method getValue(String) is undefined for the type Class<capture#3-of ? extends String>

我不会表示明确。我会自动施加更多的暗示。

2 个答案:

答案 0 :(得分:9)

问题是myTypes列表被声明为List<MyType>,它使用raw type MyType而不是MyType中的List<MyType<String>>的特定参数化名单。 This is generally discouraged, warned against, bad practice, etc.

通常,您会将列表声明为List<MyType<Integer>>MyType<String>。这将使您能够在不必投射的情况下获取元素。但是,这是有问题的,因为您希望能够在相同的列表中混合MyType<Integer>List<MyType<?>>。同样,这通常不推荐,并且是code smell

所以你可以声明List<MyType>,而不是user.setName((user.getName().getClass()) object);,但不是很多。唯一正确的结论是设计本质上存在缺陷:不要试图在集合中混合异构类型。*


  

MyType类只是一个抽象的例子。实际上我的问题是如何施放:Map<Class<T>, MyType<T>>如果对象是Object object =“foobar”;

无论如何,问题仍然是从根本上说你在列表中使用原始类型。您似乎最好使用维护类型参数化的内容,例如List<MyType>而不是{{1}}。

请考虑在此处应用the strategy pattern


*专家模式:除非有一个明智的常用超类型,您可以将其用作上限。

答案 1 :(得分:3)

我同意Matt Ball's answer 100%同意。一个简单,快速的解决方案,虽然可能不是理想的解决方案,但是从MyType中删除抽象性并添加将值作为特定类型获取的能力。您可以在标准库中的ResultSet中找到这种模式,以及其他地方:

public class MyType {
    private String content;
    MyType(String content) { this.content = content }
    public String getStringValue() { return content; }
    public Integer getIntValue() { return Integer.parseInt(content); }
}