是否可以使用String的内容强制转换Object?

时间:2015-12-08 18:44:29

标签: java string casting runtime

回顾性说明:这个问题的大部分都没有多大意义。这是我的第一个问题,并且充满了关于抽象类如何工作的错误假设。我不会删除它,因为可以从中学到一些东西,但我知道没有太多有用的信息可以从中提取。

您需要知道的事情:

我有一个名为Component ...的抽象基类

public abstract class Component
{
    public abstract void doStuff();
}

我有一些Component的子类...

public class Camera extends Component
{
    @Override
    public void doStuff() {
        //method specific to Camera objects
    }
}

public class Transform extends Component
{
    @Override
    public void doStuff() {
        //method specific to Transform objects
    }
}

问题:

我需要一个方法可以迭代HashMap中的每个组件并调用相应的“doStuff();”每种方法。

我的第一个方法是做这样的事情......

示例驱动程序#1:

public class Foo
{
    HashMap<String, Component> components;

    public Foo()
    {
        components = new HashMap<String, Component>();
        components.put("Camera", new Camera());
        components.put("Transform", new Transform());
    }

    public void bar()
    {
        //Assuming I don't know exactly what components are in the HashMap...
        //Iterate through all components,
        //Cast them to appropriate type,
        //Call "doStuff();" in all components.

        Iterator iterator = components.iterator();
        while(iterator.hasNext())
        {
            Entry componentPair = (Entry) iterator.next();
            Component component = (Component) componentPair.getValue();
            component.doStuff();
        }
    }
}

但这段代码错了。 在上面的例子中,每次调用 component.doStuff(); 时,我都会在Component基类中调用空的doStuff方法。因此,没有子类 doStuff(); 方法实际上被称为

请记住,我想要向Component投射任何东西;我想将仅转换为Component的子类

对于我的第二种方法,我尝试使用相关的字符串...

来转换组件

示例驱动程序#2:

...
while(iterator.hasNext());
{
    Entry componentPair = (Entry) iterator.next();
    String mapKey = componentPair.getKey().toString();
    Object mapValue = componentPair.getValue();
    Object component = Class.forName(mapKey).cast(mapValue);
    component.doStuff();
}
...

无法编译,因为组件被视为Object类型而 doStuff(); 不是Object类中的方法。

最后的想法:

是否有解决此问题的方法不需要重新构建代码? 我可能非常糟糕地设计/构建了这个程序,因为我很确定使用Java无法进行动态转换。 如果是这样的话,有人能告诉我解决问题的好方法吗?也许使用接口代替?

3 个答案:

答案 0 :(得分:0)

你的第一种方法是要走的路。

假设你有你描述的HashMap:

HashMap<String, Component> components = new HashMap<String, Component>();
components.put("Camera", new Camera());
components.put("Transform", new Transform());

如果需要键,可以迭代Map的EntrySet。如果您只想调用函数,可以使用map的value()函数。这样你也不需要迭代器结构,但你可以为每个循环使用a,在我看来这看起来更好。

for(Component nextComponent : components.values()){
    // do some other stuff here
    nextComponent.doStuff();
}

抽象方法不会被调用,你也不需要在这里投射任何东西,因为编译器已经知道要调用哪个函数。

答案 1 :(得分:0)

只要我记得,HashMap没有iterator()方法。

这种方法可以很好地工作,而不是entrySet上的迭代器。

Iterator<Entry<String, Component>> iterator = components.entrySet().iterator();
while (iterator.hasNext()){
    iterator.next().getValue().doStuff();
}

或者如果您只需要值

Iterator<Component> iterator = component.values().iterator();
while (iterator.hasNext()){
    iterator.next().doStuff();
}

答案 2 :(得分:0)

在运行时,Component component将是CameraTransform的实例或Component抽象类的任何其他实现。考虑到多态性(我建议你看一些关于它的文章,比如https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html),将调用overriden doStuff()方法。您不需要明确地将Component实例投射到CameraTransform,因此您的第一个示例就是可行的方法。

   for (Component component : components.values()){
         // component may be a Camera or Transform. It doens't matter; override will be called.
        component.doStuff();
    }