#java #intellij-idea #reactive-programming #project-reactor #stringbuilder
Вопрос:
Почему IntelliJ IDEA показывает предупреждение «Неподходящий вызов метода блокировки», когда один StringBuilder
добавляет другой?
public Mono<String> doSomethingReactive() {
final StringBuilder sb1 = new StringBuilder("hello");
final StringBuilder sb2 = new StringBuilder("world");
sb1.append(sb2); // This append() causes warning "Inappropriate blocking method call"
sb1.append(sb2.toString()); // ... but this append() is OK :)
return Mono.just(sb1.toString());
}
Комментарии:
1. Я подозреваю, что это IntelliJ особенный. Если бы мы говорили об
StringBuffer
этом, все было бы по-другому, ноStringBuilder
у AFAIK нет кода блокировки.2. @MichaelBerry Я создал проблему в инструменте отслеживания JetBrains: youtrack.jetbrains.com/issue/IDEA-282947
Ответ №1:
Я подозреваю, что это ошибка в ИДЕЕ IntelliJ, если только кто-нибудь не даст разумного объяснения. Видишь https://youtrack.jetbrains.com/issue/IDEA-282947
Ответ №2:
Я думаю, что это блокирует, так что, возможно, именно поэтому IntelliJ жалуется. Поскольку вы создаете Моно в конце метода, все, что предшествует этому, выполняется до или вне потока Моно. Это противоречит цели реактивного потока. Если я поставлю Моно вверху, то без предупреждения:
public Mono<String> doSomethingReactive() {
return Mono.just(new StringBuilder("hello"))
.map(sb1 -> {
StringBuilder sb2 = new StringBuilder("world");
sb1.append(sb2);
sb1.append(sb2.toString());
return sb1.toString();
});
}
В этом случае только создание первого StringBuilder выполняется вне монопотока.
Кроме того, имейте в виду, я думаю, что IntelliJ может подумать, что sb1.append(sb2)
это вызов Object::toString (), который вполне может блокировать, когда он кэширует имя класса в виртуальной машине, тогда sb1.append(sb2.toString())
как называется StringBuilder::toString (), который может не блокировать.