迭代对象并以铸造方式访问它们

时间:2016-03-04 09:56:50

标签: java reflection

我试图迭代地图并投射对象,然后以某种方式将它们引用为已经投射过。

假设Test1Test2是完全不同的类,但两者都有一个名为get_class_specific_field()的方法

HashMap<Class,Object> objects = new HashMap<>();

然后分别在Test1Test2类中进行:

objects.put(Test1.class,this);

objects.put(Test2.class,this);

这是一种常规的迭代方式:

for( Map.Entry<Class, Object> entry : objects.entrySet()){
    if(Object instanceof Test1){
        Test1 castedObj = (Test1)entry.getValue();
        castedObj.get_class_specific_field();
    }

    if(Object instanceof Test2){
        Test2 castedObj = (Test2)entry.getValue();
        castedObj.get_class_specific_field();
    }
}

是否有可能以某种方式避免阻塞,例如

for( Map.Entry<Class, Object> entry : objects.entrySet()){
    ???? castedObj = entry.getValue()).cast(entry.getKey());
    castedObj.get_class_specific_field(); 
}

还有其他方法吗?

3 个答案:

答案 0 :(得分:1)

使用接口,只需转换到该接口即可。

如果你不能这样做,你可以使用反射并查找方法,但这可能会破坏,例如如果方法名称改变等。

另一种方法是使用某种知道如何处理特定类的处理程序,并根据该类选择该处理程序。

示例:

interface Handler {
  void handle( Object o );
  Class<?> getHandledClass();
}

class Test1Handler implements Handler() {
  public void handle( Object o ) {
    ((Test1)o).callSomeSpecificMethod();
  }

  public Class<?> getHandledClass() {
    return Test1.class;
  }      
}

用法:

Map<Class<?>, Handler> handlers = ...;
Test1Handler test1Handler = new Test1Handler();
handlers.put( test1Handler.getHandledClass(), test1Handler );
//and others

for( Map.Entry<Class, Object> entry : objects.entrySet()){
  Handler h = handlers.get( entry.getKey() ); //ofc you need to "handle" unknown types etc. ;)
  h.handle( entry.getValue() );
}

答案 1 :(得分:0)

没有简单的方法将类型放在左边。你有几个选择。

1)

Class c = entry.getKey();
Object castedObj = entry.getValue()
castedObj.cast(c).get_class_specific_field(); // cast every time

每次施法都不漂亮,但也不会影响性能。它仅与编译器和代码阅读器相关。

2)使用一些接口/类层次结构并覆盖get_class_specific_field

3)使用访客设计模式。

答案 2 :(得分:0)

创建

interface SpecialFieldGetter<T>{
      T get_class_specific_field();
}

在Test1和Test2中实现接口