0

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

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>

我不会明确地投射。我会更加隐式/自动地投射。

4

2 回答 2

9

问题在于myTypes列表被声明为 a List<MyType>,它使用原始类型 MyType而不是列表中的特定参数化MyType通常不鼓励这样做,警告不要这样做,不好的做法等。

通常你会像List<MyType<String>>or一样声明这个列表List<MyType<Integer>>。这将使您能够在无需强制转换的情况下取出元素。但是,这是有问题的,因为您希望能够混合MyType<String>MyType<Integer>同一个列表中。同样,这通常是不推荐的,而且是代码异味

所以你可以声明 a List<MyType<?>>,它比 好List<MyType>,但不是很多。唯一正确的结论是设计本身就有缺陷:不要尝试在集合中混合异构类型。*


MyType 类只是一个抽象示例。实际上我的问题是我如何转换:user.setName((user.getName().getClass()) object);if object is Object object = "foobar";

无论如何,问题基本上仍然是您在列表中使用原始类型。似乎您最好使用维护类型参数化的东西,例如 aMap<Class<T>, MyType<T>>而不是 a List<MyType>

考虑在此处应用策略模式


*专家模式:除非有一个合理的通用超类型可以用作上限。

于 2013-02-23T15:43:59.047 回答
3

我 100% 同意Matt Ball 的回答。一个简单、快速的解决方案(虽然可能不是理想的解决方案)是从 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); }
}
于 2013-02-23T15:52:13.513 回答