4

我继承了一个使用 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
    }
  }
}

谢谢!

4

2 回答 2

4

当你声明一个内部类时

class Outer {
    class Inner {
    }
}

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

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

想象一下,外面的班级里面有各种各样的领域,而且很大。现在假设您只想序列化内部类,如果您尝试这样做,您会惊讶地发现整个内部和外部实例都将被序列化,从而获得更慢和更大的体验。

通过用“静态”装饰内部类,您正在删除对外部类的合成字段引用,并阻止这种情况发生。

有一个正常的内部类会导致其他一些事情。例如,如果不创建外部类,就无法创建内部类的实例,这会导致非常神秘的语法,例如

Outer.Inner i = new Outer().new Inner();
于 2018-04-27T04:35:23.367 回答
2

目前尚不清楚具体警告的含义。如果您的唯一目标是删除警告,那么鉴于您的内部类没有实现接口,您可以简单地将其转换为静态方法。

@Mapper
public interface SubjectRepositoryService {
    //...

    static String search(final SubjectSearch subjectSearch) {
        //... some string generation
    }
}
于 2018-04-10T17:42:33.310 回答