在 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
}
}
我有一个非常胖的 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
}
}