Java Reflection如何实例化类字段类型

时间:2018-08-05 13:41:51

标签: java reflection

我有一个我要通过反射实例化的跟随类,然后自动实例化它的字段'databaseService'

@Controller
public class BaseController {

        @AutoInstantiate
        private DatabaseService databaseService;

        @AfterSetup
        public void initialize() {

                System.out.println("Testing " + databaseService.getEntry());

        }
    }

我正在尝试自动实例化的简单类

public class DatabaseService {

    public DatabaseService() {}

    public String getEntry() {

        return "I'm working! ";
    }
}

我要做什么

public class Instantiator {

    private static void start() {

        Reflections reflections = new Reflections("com");
        Class<?> clazz = reflections.getTypesAnnotatedWith(Controller.class)[0];

         //Assume 'clazz' is 'BaseController' (the parent class of DatabaseService)

        for(Field field : clazz.getDeclaredFields()) {

            if(field.isAnnotationPresent(AutoInstantiate.class)) {

                try {

                    field.setAccessible(true);

                    Object autowiredObject = field.getType().newInstance();

                    //HERES WHERE IT ALWAYS FAILS
                    field.set(clazz, autowiredObject);

                }
                catch(Exception e) {

                    logger.severe("Failure invoking class " + clazz.getName() + " Problem : " + e.getMessage());
                }
            }
        }
    }
}

和简单的主线

public class App {

    public static void main(String[] args) throws Exception {

        Instantiator.start();
    }
}

问题 严重:调用类com.controller.BaseController失败问题:无法将com.service.DatabaseService字段com.controller.BaseController.databaseService设置为java.lang.Class

总体问题: 我不确定如何将实例化的类Object(DatabaseService)设置回其父类(BaseController)

1 个答案:

答案 0 :(得分:1)

这是您遇到的问题:

field.set(autowiredObject.getClass(), autowiredObject);

看看documentationField.set(Object, Object)方法的参数。我引用了一部分:

  

参数:

     

obj-应该修改其字段的对象

     

value-要修改的obj字段的新值

(如果该字段是静态的,则应该放null来代替obj)。

这意味着您实际上应该将与clazz类型相同的目标实例作为Field.set(Object, Object)方法中的第一个参数,因为您要修改字段的目标实例没有DatabaseService的Class对象。但是,您丢失了一个用ControllerBaseController注释的类型的实例,稍后将对其进行修改。