是否可以使用字符串的内容来转换对象?
Is it possible to cast an Object using the contents of a String?
回顾笔记:这个问题大部分都没有多大意义。这是我的第一个问题,充满了关于抽象 classes 如何工作的错误假设。我不会删除它,因为可以从中学到一些东西,但我知道没有太多有用的信息可以从中提取。
你需要知道的事情:
我有一个名为 Component 的抽象基础 class...
public abstract class Component
{
public abstract void doStuff();
}
我有一些组件的子classes...
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(); 时,我都会调用组件基 class 中的空 doStuff 方法。因此subclassdoStuff();方法的none其实是调用了.
记住,我不想将任何内容转换为组件;我只想将 转换为 Component.
的 subclasses
对于我的第二种方法,我尝试使用相关的字符串来转换组件...
示例驱动程序#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();
}
...
但是这个 不会编译 因为组件被视为对象类型并且 doStuff(); 不是对象 class.
最后的想法:
是否有不需要重新构建代码的解决方案?
我有可能 designed/structured 这个程序真的很糟糕,因为我很确定 Java 无法进行动态转换。
如果是这样,谁能告诉我解决问题的好方法?也许改用接口?
你的第一个方法就是要走的路。
假设您有您描述的 HashMap:
HashMap<String, Component> components = new HashMap<String, Component>();
components.put("Camera", new Camera());
components.put("Transform", new Transform());
如果需要键,可以遍历Map的EntrySet。如果您只想调用函数,可以使用地图的 values() 函数。这样你也不需要迭代器结构,但你可以使用 for each 循环,我认为这看起来更好。
for(Component nextComponent : components.values()){
// do some other stuff here
nextComponent.doStuff();
}
抽象方法不会被调用,你也不需要在这里强制转换任何东西,因为编译器已经知道要调用哪个函数。
据我所知,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();
}
在运行时,Component component
将是 Camera
或 Transform
的实例或 Component
抽象 class 的任何其他实现。考虑到多态性(我建议你看一些关于它的文章,比如 https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html),覆盖的 doStuff()
方法将被调用。您不需要将 Component
实例显式转换为 Camera
或 Transform
,因此您的第一个示例就是要走的路。
for (Component component : components.values()){
// component may be a Camera or Transform. It doens't matter; override will be called.
component.doStuff();
}
回顾笔记:这个问题大部分都没有多大意义。这是我的第一个问题,充满了关于抽象 classes 如何工作的错误假设。我不会删除它,因为可以从中学到一些东西,但我知道没有太多有用的信息可以从中提取。
你需要知道的事情:
我有一个名为 Component 的抽象基础 class...
public abstract class Component
{
public abstract void doStuff();
}
我有一些组件的子classes...
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(); 时,我都会调用组件基 class 中的空 doStuff 方法。因此subclassdoStuff();方法的none其实是调用了.
记住,我不想将任何内容转换为组件;我只想将 转换为 Component.
的 subclasses对于我的第二种方法,我尝试使用相关的字符串来转换组件...
示例驱动程序#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();
}
...
但是这个 不会编译 因为组件被视为对象类型并且 doStuff(); 不是对象 class.
最后的想法:
是否有不需要重新构建代码的解决方案? 我有可能 designed/structured 这个程序真的很糟糕,因为我很确定 Java 无法进行动态转换。 如果是这样,谁能告诉我解决问题的好方法?也许改用接口?
你的第一个方法就是要走的路。
假设您有您描述的 HashMap:
HashMap<String, Component> components = new HashMap<String, Component>();
components.put("Camera", new Camera());
components.put("Transform", new Transform());
如果需要键,可以遍历Map的EntrySet。如果您只想调用函数,可以使用地图的 values() 函数。这样你也不需要迭代器结构,但你可以使用 for each 循环,我认为这看起来更好。
for(Component nextComponent : components.values()){
// do some other stuff here
nextComponent.doStuff();
}
抽象方法不会被调用,你也不需要在这里强制转换任何东西,因为编译器已经知道要调用哪个函数。
据我所知,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();
}
在运行时,Component component
将是 Camera
或 Transform
的实例或 Component
抽象 class 的任何其他实现。考虑到多态性(我建议你看一些关于它的文章,比如 https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html),覆盖的 doStuff()
方法将被调用。您不需要将 Component
实例显式转换为 Camera
或 Transform
,因此您的第一个示例就是要走的路。
for (Component component : components.values()){
// component may be a Camera or Transform. It doens't matter; override will be called.
component.doStuff();
}