简体   繁体   English

如何在java项目中找到哪个数据类没有覆盖toString()方法

[英]How to find which data class not overriden toString() method in java project

In our project certain data classes (POJO used for API Request & Response) are overridding the toString() method to provide meaningful information - but certain data classes are not overridden toString() .在我们的项目中,某些数据类(POJO used for API Request & Response)覆盖了toString()方法以提供有意义的信息 - 但某些数据类没有覆盖toString()

When application print the logs of data class in which toString() is not overridden, they are not printing meaningful information they just call object class toString() .当应用程序打印没有覆盖toString()的数据类的logs时,它们不会打印有意义的信息,它们只是调用对象类toString()

So we want to identify those data class and provide toString() implementation .所以我们要识别那些数据类并提供toString() implementation

Is there any way to identify those kind of class in which toString() method is not implemented .有什么方法可以识别没有implemented toString()方法的那些类。

Looking in every data class and checking for toString() method is tedious and time consuming task.查看每个数据类并检查toString()方法是一项繁琐且耗时的任务。

Is there any better way to do that using some tools like eclipse or something else?有没有更好的方法可以使用诸如 eclipse 或其他工具之类的工具来做到这一点?

When the class is not overriding toString() - it must be using the default implementation which contains the class name. 当类未覆盖toString() -它必须使用包含类名称的默认实现。 Thus: check your logs and work backwards! 因此:检查您的日志并向后工作!

Alternatively, you can make use of reflection: 另外,您可以使用反射:

  • start a JVM run that contains all your classes in the classpath 开始在类路径中包含所有类的JVM运行
  • scan the class path for all your classes (or if possible: those that resemble your POJOs) 扫描所有类的类路径(或者如果可能的话:那些像你的POJO)
  • check each class if it implements toString() 检查每个类是否实现toString()

Obviously that is a lot of work - but there is no technical reason why this shouldn't work out. 显然,这需要进行大量工作-但没有技术原因无法解决。 Of course your main problem here might be to reduce the number of classes to look at - a list that contains 500 classes wouldn't be too helpful either. 当然,这里的主要问题可能是减少要查看的类的数量-包含500个类的列表也不会有太大帮助。

And one other (potential) option: create a PojoBase class that uses reflection to implement toString() and maybe equals()/hashCode() - and then simply ensure that all your POJO classes extend that base class. 还有一个(潜在的)选项:创建一个PojoBase类,该类使用反射来实现toString()以及equals()/ hashCode()-然后简单地确保所有POJO类都可以扩展该基类。 (Disclaimer: of course you have to understand the consequences of doing such things. But we lately create such a BaseBean that is using the Apache Commons EqualsBuilder, ... calls this way) (免责声明:当然,您必须了解这样做的后果。但是,最近我们使用Apache Commons EqualsBuilder创建了这样的BaseBean ,以这种方式调用)

Here is an idea that works if your data classes have a common abstract class they inherit from. 如果您的数据类具有从其继承的公共抽象类,则这是一个可行的想法。

Introduce an abstract toString() in your superclass: 在您的超类中引入一个抽象的toString()

public abstract String toString();

This will force all subclasses to override it and you will get compile errors if they don't. 这将强制所有子类重写它,否则,您将得到编译错误。

Sadly this method has a major constraint. 可悲的是,这种方法有很大的限制。 If you have something like this: 如果您有这样的事情:

abstract class A {
    public abstract String toString();
}

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

class C extends B {
}

it will not notice the missing toString() in C . 它不会注意到C缺少的toString()

This method might not work for you but I thought I'd post it anyway so maybe it'll help others who read your question. 这种方法可能对您不起作用,但是我认为我还是会发布它,因此它可能会对阅读您问题的其他人有所帮助。

Use reflection. 使用反射。 In my project, I write test for each domain object. 在我的项目中,我为每个域对象编写测试。 Test checks if toString method comes from Object class or from my class. 测试检查toString方法是来自Object类还是来自我的类​​。 Code for that test 该测试的代码

/**
     * 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();
    }

Then having class SomeClass , In SomeClassTest I invoke it as follows 然后有类SomeClass ,在SomeClassTest我按如下方式调用它

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

If you want to identify all classes that do not override toString, you may write tool that will scan classpath and invoke such test for every class (from your package). 如果要标识所有不覆盖toString的类,则可以编写工具来扫描类路径并为每个类(从包中)调用此类测试。 But this approach has limitations. 但是这种方法有局限性。 Not all classes require toString. 并非所有类都需要toString。 Service classes, REST controllers, etc do not need toString. 服务类,REST控制器等不需要toString。 So automation will give you a lot of false positives. 因此,自动化将给您带来许多误报。 You may scan only packages with model classes (if you keep model in separate package) or annotate model classes with custom annotation (and then scan only annotated classes) but I think such solutions are not worth the effort. 您可以只扫描具有模型类的包(如果将模型保存在单独的包中),也可以使用自定义注释对模型类进行批注(然后仅扫描带注释的类),但是我认为这样的解决方案不值得付出努力。

Finally, you may use https://projectlombok.org/ https://immutables.github.io/ or https://github.com/google/auto/tree/master/value Those libraries use code generation/anotation processing to auto-generate equals/hashcode/toString. 最后,您可以使用https://projectlombok.org/ https://immutables.github.io/https://github.com/google/auto/tree/master/value那些库使用代码生成/注释处理来自动生成equals / hashcode / toString。 I use Immutables and it works very well. 我使用不可变对象,并且效果很好。 Even migration legacy data model to Immutables is straightforward. 甚至将遗留数据模型迁移到Immutables也很简单。

In my project, I write such test for every domain object. 在我的项目中,我为每个域对象编写了这样的测试。

One way is to use Reflections Library to obtain all classes within a given package, note that this does not work on classes like anonymous, private, partial, inaccessible, ..etc, so the best way is to do it manually as per @GhostCat answer 一种方法是使用反射库获取给定包中的所有类,请注意,这不适用于匿名,私有,部分,不可访问,.. etc等类,因此最好的方法是按照@GhostCat手动进行回答

Now should you go this route, here's how it could be done, first obtain classes through Reflections Library, quoted from this answer by @Staale 现在,您应该走这条路线,这是可以完成的方法,首先通过反射库获取类,@ Staale 对此答案 引用

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

Then iterate over the classes, and check if toString is declared in the class itself 然后遍历这些类,并检查是否在类本身中声明了toString

for(Class clazz : allClasses)
{
    if(!clazz.getMethod("toString").getDeclaringClass().getName().equals(clazz.getName()))
        System.out.println("toString not overridden in class "+clazz.getName());
}

实际上应该很简单,只需检查是否可以通过.getDeclaredMethod("toString")检索 toString 方法,如果此语句触发java.lang.NoSuchMethodException ,则它未在您的焦点类中声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在java中编译Object类的toString()方法? - How is the toString() method of Object class compiled in java? 在Java中,如果我从子类中调用一个超类方法,该超类方法将调用重写方法,那么将调用哪个类的方法? - In java, if I call, from a subclass, a superclass method that calls an overriden method, which class' method will be called? Java:如何找到数组中价格最小的所有对象并使用 Check 类中的 toString 方法打印它? - Java: How to find all object with the smallest price in the array and print it using toString method in Check class? java - 当抽象类中的方法调用已被覆盖的方法时,继承如何在java中工作? - how does inheritance work in java when a method in abstract class call a method that has been overriden? 在Groovy中,println不使用重写的toString方法 - println does not use overriden toString method in Groovy Java:如何在另一个类中使用一个类的toString()方法? - Java: How to use the toString() method of one class in an other one? 如何在Java中的同一个类中为多个枚举成员使用toString()方法 - how to use the toString() method for multiple enum members in same class in Java 为什么我的toString()类被自动覆盖? - Why is my toString() class being automatically Overriden? 如何覆盖类中的 toString 方法 - How to override toString method in a class 如何检查 class 是否使用 Kotlin 或 Java 中的反射从接口覆盖了默认方法? - How to check if a class has overriden a default method from an interface using Reflection in Kotlin or Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM