代码之家  ›  专栏  ›  技术社区  ›  Snehal Patel

如何在java项目中找到未重写toString()方法的数据类

  •  2
  • Snehal Patel  · 技术社区  · 7 年前

    在我们的项目中,某些数据类 (POJO used for API Request & Response) 正在覆盖 toString() .

    当应用程序打印 logs toString() 不会被重写,它们不会打印有意义的信息,它们只是调用对象类 toString()

    因此,我们希望识别这些数据类并提供 implementation .

    有什么方法可以确定哪些类别 toString() 方法不是 implemented .

    该方法是一项繁琐而耗时的任务。

    有没有更好的方法可以使用eclipse或其他工具来实现这一点?

    5 回复  |  直到 7 年前
        1
  •  3
  •   Khaled.K    7 年前

    当类未重写时 toString() -它必须使用默认实现 类名。因此:检查日志并反向工作!

    或者,您可以利用反射:

    • 启动包含以下内容的JVM运行 全部的
    • 扫描 你的 类(或者,如果可能的话:类似于您的pojo的类)
    • toString()

    显然,这是一个很大的工作-但没有技术原因为什么这不应该工作。当然,这里的主要问题可能是减少要查看的类的数量——一个包含500个类的列表也不会有太大帮助。

    还有一个(潜在的)选项:创建一个PojoBase类,该类使用 反射 实现toString()和equals()/hashCode()-然后简单地确保所有POJO类都扩展了该基类。(免责声明:当然,你必须理解这样做的后果。但我们最近创建了这样一个 BaseBean 即使用Apache Commons EqualsBuilder,…以这种方式调用)

        2
  •  2
  •   Khaled.K    7 年前

    Reflections Library 要获取给定包中的所有类,请注意,这不适用于匿名、私有、部分、不可访问等类,因此最好的方法是根据 @幽灵猫 答复

    this answer 通过 @斯塔尔

    Reflections reflections = new Reflections("my.project.prefix");
    
    Set<Class<? extends Object>> allClasses =
                reflections.getSubTypesOf(Object.class);
    

    然后迭代类,并检查toString是否在类本身中声明

    for(Class clazz : allClasses)
    {
        if(!clazz.getMethod("toString").getDeclaringClass().getName().equals(clazz.getName()))
            System.out.println("toString not overridden in class "+clazz.getName());
    }
    
        3
  •  2
  •   André Stannek    7 年前

    介绍摘要 toString() 在您的超类中:

    public abstract String toString();
    

    这将迫使所有子类重写它,如果不重写,则会出现编译错误。

    不幸的是,这种方法有一个主要的限制。如果你有这样的东西:

    abstract class A {
        public abstract String toString();
    }
    
    class B extends A {
        public String toString() {
            return "foo";
        }
    }
    
    class C extends B {
    }
    

    它不会注意到丢失的 在里面 C .

    这个方法可能不适合你,但我想无论如何我都会发布它,这样也许它会帮助其他阅读你问题的人。

        4
  •  1
  •   Bartosz Bilicki Ievgen Lukash    7 年前

    使用反射。在我的项目中,我为每个域对象编写测试。测试检查是否 toString 方法来自 Object 还是我的课。该测试的代码

    /**
         * Passes if class has overridden toString method. Fails otherwise.
         */
        public static void toStringTest(Object o) throws NoSuchMethodException {
            Class<?> clazz = o.getClass().getMethod("toString").getDeclaringClass();
            assertThat(clazz).isNotEqualTo(Object.class)
                    .withFailMessage("expecting method toString to be defined in actual class");
            assertThat(o.toString()).isNotEmpty();
        }
    

    SomeClass 在里面 SomeClassTest 我调用它如下

       public void shouldOverrideToString() throws NoSuchMethodException {
            TestUtils.toStringTest(new SomeClassTest());
        }
    

    若你们想识别所有并没有覆盖toString的类,你们可以编写一个工具来扫描类路径,并为每个类(从你们的包中)调用这样的测试。但这种方法有局限性。并非所有类都需要toString。服务类、REST控制器等不需要字符串。所以自动化会给你带来很多误报。您可以只扫描带有模型类的包(如果您将模型放在单独的包中)或使用自定义注释注释模型类(然后只扫描带注释的类),但我认为这样的解决方案不值得这么做。

    https://projectlombok.org/ https://immutables.github.io/ https://github.com/google/auto/tree/master/value

    在我的项目中,我为每个域对象编写了这样的测试。

        5
  •  0
  •   luca84    3 年前

    .getDeclaredMethod("toString") ,如果此语句触发 java.lang.NoSuchMethodException ,那么它就不会在你的焦点类中声明。