Java/SpotBugs,什么是 "named static inner class",如果它是在接口中声明的?

Java/SpotBugs, What is a "named static inner class", if it's being declared in an interface?

我继承了一个使用 MyBatis 的代码库。 SpotBugs 告诉我 SubjectRepositoryQueries could be refactored into a named _static_ inner class. 我从未遇到过这个词,我希望有人能解释它究竟要求我做得更好。看起来 SubjectRepositoryQueries 实际上是命名的(它不是匿名的),而且它已经是静态的。 SubjectRepositoryQueries 不能声明为私有,因为它在接口内。

@Mapper
public interface SubjectRepositoryService {
  @SelectProvider(type = SubjectRepositoryQueries.class, method = "search")
  List<Subject> search(SubjectSearch subjectSearch);

  static final class SubjectRepositoryQueries {
    public String search(final SubjectSearch subjectSearch) {
      ... some string generation
    }
  }
}

谢谢!

不清楚具体的警告是什么意思。如果您的唯一目标是删除警告,那么考虑到您的内部 class 没有实现接口,您可以简单地将其转换为静态方法。

@Mapper
public interface SubjectRepositoryService {
    //...

    static String search(final SubjectSearch subjectSearch) {
        //... some string generation
    }
}

当你声明一个内部 class

class Outer {
    class Inner {
    }
}

即使您没有在 Inner 中声明任何字段,java 编译器也会自动插入一个包含外部 class 引用的合成字段,通常称为 $0。因此,如果您 运行 javap 位于内部 class,您将看到它。

这个想法是,在很多情况下,拥有该引用变量是一种浪费 space,更重要的是会导致序列化之类的事情导致意外问题。

想象一下,外层class里面有各种各样的场,而且是巨大的。现在假设您只想序列化内部 class,如果您尝试这样做,您会惊讶地发现整个内部和外部实例都将被序列化,从而导致更慢但更大的体验。

通过用 'static' 修饰内部 class,您将删除对外部 class 的合成字段引用,并阻止这种情况发生。

还有一些其他原因是由正常的内在 class 引起的。例如,你不能在不创建外部 class 的情况下创建内部 class 的实例,这会导致非常神秘的语法,如

Outer.Inner i = new Outer().new Inner();