在 java 中查找对方法调用的引用,以使用反射清理未使用的 pojo 字段

Find references to method invocations in java to clean up unused pojo fields using reflection

我有一个非常胖的 pojo java class 有超过 1000 个字段/getter 和 setter。其中一些字段不再使用,我想清理 class。我不太了解反射,但我希望能够以编程方式识别另一个 class 中不再引用的字段。

识别字段是否需要清理的方法是查看字段的 setter 方法是否正在另一个中调用,如果没有,则它是清理的候选者。

我已经弄清楚如何使用反射提取方法和字段名称,但我不知道从哪里开始识别那些在另一个 class 的执行中未引用其设置器的字段。

public class GetterSetterReflec {

    public static void main(String args[]){
        printGettersSetters(SearchEngineClientModel.class);
    }

    public static void printGettersSetters(Class<?> aClass)
    {
          Method[] methods = aClass.getMethods();

          Field[] fields = aClass.getDeclaredFields();
          for(Field field : fields){
              System.out.println(field);
          }

          for(Method method : methods){
            if(isGetter(method)) System.out.println("getter: " + method);
            if(isSetter(method)) System.out.println("setter: " + method);
          }
    }

        public static boolean isGetter(Method method){
          if(!method.getName().startsWith("get"))      return false;
          if(method.getParameterTypes().length != 0)   return false;  
          if(void.class.equals(method.getReturnType()))
                  return false;
          return true;
        }

        public static boolean isSetter(Method method){
          if(!method.getName().startsWith("set")) return false;
          if(method.getParameterTypes().length != 1) return false;
          return true;
        }
}

如果您能提供任何帮助,我将不胜感激。提前致谢!

我认为这不可能通过反射实现。您可以使用 IDE(或其他静态分析工具)来发现调用层次结构。这种方法在 99% 的时间内都有效,但对于在 运行 时间通过反射(例如,通过框架)执行的任何调用都会失败。

如果你想赶上 运行time 电话,你可以建议使用 AOP 的方法。一种更简单的方法可能是从您怀疑未使用的方法中引入日志语句(或抛出异常),然后 运行 您的测试。如果您的测试覆盖率很低,您可以将日志语句引入可疑方法,然后让您的应用程序在生产中 运行 一段时间(使用标记语句),直到您有足够的信心删除可疑方法。


动态方法调用示例[​​=21=]

考虑以下 Spring bean:

public class Foo implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext ctx) 
             throws BeansException {
        // you won't find any reference to this setter; 
        // ...it is invoked at runtime by the Spring framework

    }

}