Java/SpotBugs, что такое "именованный статический внутренний класс", если он объявлен в интерфейсе?
Я унаследовал кодовую базу, которая использует 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
}
}
}
Спасибо!
2 ответа
Непонятно, что означает конкретное предупреждение. Если ваша единственная цель - удалить предупреждение, то, учитывая, что ваш внутренний класс не реализует интерфейс, вы можете просто преобразовать его в статический метод.
@Mapper
public interface SubjectRepositoryService {
//...
static String search(final SubjectSearch subjectSearch) {
//... some string generation
}
}
Когда вы объявляете внутренний класс
class Outer {
class Inner {
}
}
даже если вы не объявили никаких полей во Inner, компилятор java автоматически вставит синтетическое поле, которое содержит ссылку на внешний класс, обычно называемое чем-то вроде этого $0. Так что, если вы запустите javap во внутреннем классе, вы увидите это.
Идея состоит в том, что во многих случаях наличие этой ссылочной переменной является пустой тратой пространства и, что более важно, приводит к тому, что такие вещи, как сериализация, вызывают непредвиденные проблемы.
Представьте, что во внешнем классе были все виды полей, и он был массивным. Теперь представьте, что вы хотите сериализовать только внутренний класс, если вы попытаетесь это сделать, вы будете удивлены, обнаружив, что весь внутренний и внешний экземпляр будут сериализованы, что приведет к гораздо более медленному и большему опыту.
Декорируя внутренний класс с помощью "static", вы удаляете эту синтетическую ссылку на поле внешнего класса и не допускаете этого.
Есть и другие вещи, которые вызывает нормальный внутренний класс. Например, вы не можете создать экземпляр внутреннего класса, не создавая внешний класс, который вызывает действительно загадочный синтаксис, такой как
Outer.Inner i = new Outer().new Inner();