final int roundCarryMask = (1 << (bitShiftsInWord - 1)); // <=
Это тоже вообще не ошибка. Я потому не делаю подобные unsound-варнинги, потому что в них сбалансировать false-positive/false-negative очень сложно. Здесь откровенно мусорный варнинг, который только отвлечёт программистов от реальных проблем. Видите выше noRestore = bitShiftsInWord == 0? А ниже посмотрите на использования noRestore. Вы сразу увидите, что когда bitShiftsInWord == 0, результат битового сдвига (переменная roundCarryMask) не используется вообще. Поэтому абсолютно наплевать, какое там значение.
Почему-то вы, кстати, молчите про другую вещь в том же методе:
Здесь очевидно noRestore всегда ложно, потому что случай wordShifts == 0 && bitShiftsInWord == 0 был обработан выше. Идея радостно подсвечивает эти ветки и предлагает автоматически упростить код в один клик. PVS-Studio не может так? ;-)
Я ж вам про это говорил вроде. Это вообще не ошибка, просто перестраховка. Вы смотрите хоть немного логику метода. Да, если на входе строка "0", она отсекается двумя разными способами, в обоих случаях return false; произойдёт, поэтому без разницы, в какую ветку мы зайдём. Может сбить с толку, если не вчитаться в код, но ошибки здесь нет. Сама Идея этот код подсвечивает ещё с 2017-го года (и не заводите волынку, что раз мы его не исправили, то нищитово).
С ArrayList у тебя стандартная проблема бенчмарк-энтузиаста, кстати. Ты увидел кейс, который в твоей практике случается часто, заточил библиотеку под этот кейс и написал бенчмарк тоже под этот кейс. Почему не потестировать другие кейсы? Если туда HashSet прилетает, сколько съедает лишняя проверка? А если разные реализации прилетают, например emptyList/singletonList/ArrayList/unmodifiableList в равной пропорции (вполне жизненная ситуация)? Насколько ускорится или замедлится каждый случай? Тело метода стало больше, влияет ли это на решения об инлайнинге?
Я не к тому, что твоя идея плоха. Она может и хороша. Я к тому, что надо критически смотреть на свои гениальные идеи.
Мораль сей басни такова: ваш гениальный патч могут зарезать на ревью просто потому, что не увидят в нём особой ценности. Ну да, есть повторяющийся код, но он никому особо не мешает, так что пусть живёт.
Дело не совсем в этом, тебе же сказали. Если делаешь метод в Arrays, нужны как минимум специализации для int/long/double, а желательно и для byte/boolean/short/char/float. В итоге имеем девять методов. И логично иметь версии с диапазоном поиска. Вот уже 18 методов. И ещё lastIndexOf — итого 36. Это уже серьёзная заявка. Люди надеются на светлое будущее и специализацию дженериков, когда можно будет обойтись четырьмя методами. Поэтому не хотят плодить новый код, связанный с речной специализацией. Только когда это будет — неясно.
Странно, что это называется assert. Это же precondition. Либо библиотека писалась для ассертов, но используется для прекондишнов. Технически разница может невелика, но семантика у ассерта и прекондишна разная.
Начнём с того, что ни у кого нет цели сделать из Джавы новый Котлин или Скалу. Какой смысл, если Котлин и Скала уже существуют? Джава — это отдельный язык со своей философией. У Котлина и Скалы другая философия. Это прекрасно, что у программистов есть выбор, какой философии следовать. Если сделать из Джавы второй Котлин, выбор пропадёт.
В Джаве есть одна хорошая вещь: в большинстве случаев локального контекста понятно, чтобы выяснить, что делает данная строчка кода. Скажем, если вы видите a[b] = c * d, вы знаете точно, что здесь у вас происходит запись произведения в элемент массива в куче, вне зависимости от того, что такое a, b, c и d, вне зависимости от того, какие у вас есть импорты и библиотеки, в каком классе вы выполняете этот код. Вы точно знаете, что в этой строчке у вас нет сетевого запроса или доступа к базе данных. В Котлине или Скале вы не уверены, эта строчка может делать абсолютно всё что угодно. Я считаю, что ясность — важная отличительная черта Джавы, и Джава перестанет быть Джавой, если потеряет ясность. Причём это усложнит не только чтение кода человеком, но и средства автоматического анализа кода. Некоторые вещи могут вообще перестать работать.
Зависит от проекта. В исходниках IntelliJ IDEA тоже многие тысячи instanceof. По сути дела многие инспекции — это поиск паттернов по дереву, паттерн-матчинг в чистом виде. Ну и в целом нет ничего плохого в instanceof, если правильно его использовать. Часто это существенно лучше, чем visitor pattern, который в джаве выглядит откровенно по-уродски, занимает больше места в исходниках и имеет больше накладных расходов при исполнении.
Если завтра будет вызывать, завтра и поменяете. Давайте сразу добавим методу тридцать дополнительных параметров, ведь они завтра могут пригодиться. Получатель невиртуального метода — это просто один из его параметров.
Правильно вызывать через экземпляр бина.
Ну если вы придумали себе надуманные правила, то тогда да, правильно.
Кажется, в этом нет смысла. Эта строчка совершенно очевидно выполняется только при cur == -1. Или сообщить, что "если бы это условие было не под if (cur == -1), оно не было бы всегда истинно"?
Это натянуто. Ты в каждом методе, принимающем коллекцию, ожидаешь увидеть в ней null? Я вот нет. Иногда метод вправе ожидать каких-то гарантий относительно аргументов. Особенно приватный метод.
Мне это не нравится. Придётся компилировать всё равно с разными таргетами, но сливать класс-файлы в одно место. Можно запутаться или сломать какие-нибудь тулзы.
Почему хуже? XML внутри XML смотрится более органично, чем груви внутри XML. И это лучше, чем Gradle.kts, потому что менее кардинально и требует меньших усилий.
Я не проверял, но говорят, что если это делать как многомодульный мавен-проект, то IDE взлетит из коробки. А здесь надо специально распознавать нестандартный плагин, который хотя и неплох, но — посмотрим правде в глаза — имеет всего 16 звёзд на гитхабе.
Не поясните? Это же фишка Java 9, как ее к андроиду-то прикручивать?
Любая джава (и даже недоджава Андроида, я надеюсь), которая не в курсе этой фичи, будет просто игнорировать лишнюю строчку в манифесте и лишние файлы внутри META-INF. Если их не учитывать, всё остальное — вполне корректная Java-8-библиотека.
Любую проблему можно решить например при помощи gmaven — написав код на груви
На вкус и цвет все фломастеры разные. Я уж скорее перейду на Gradle+Kotlin script, чем куски груви буду втыкать.
Сейчас уже интереснее, какое-то API вырисовывается. Маленькое замечание по имени — вместо toList() лучше asList(). Предлог to традиционно сигнализирует о преобразовании, а адаптеры именуются начиная с as.
Метод convertToImmutableList — это очень грязно. Чистое и понятное API гораздо лучше сомнительного прироста производительности. Но если уж вы это делаете, позвольте дать несколько советов.
Во-первых, сейчас семантика метода совершенно плохая. Он делает что-то, если что-то сработает, в зависимости от типов коллекций. А если не сработает, то результат будет другим. Надёжная система на это никогда не пойдёт. Гораздо разумнее сделать одинаковую семантику, и хачить только производительность. Можно сделать, например, метод drainToImmutableList(Collection<T> c), который всегда перегружает данные в неизменяемый список и очищает исходный (вызывая c.clear()). Для такого метода можно сделать быстрый путь для ArrayList. Он будет работать так же, даже если рефлекшн не сработает.
Во-вторых, рекомендую заменить original instanceof ArrayList<?> на original.getClass().equals(ArrayList.class). Мало ли кто какой наследник сделал и каких гарантий он ожидает в этом наследнике.
В-третьих, вы зря инициализируете поля безусловно в статическом инициализаторе. В Java 9+ пользователь библиотеки получит в консоль предупреждение о том, что используется нелегальный рефлекшн, просто когда он воспользуется вашей библиотекой, даже если не будет использовать этот спорный метод. Внутри библиотеки вы не можете это отключить, пользователю придётся писать дурацкие ключики при запуске JVM. Не каждый будет рад. Надо сделать это лениво (например, используя Initialization on demand holder idiom), чтобы не страдали те, кто не хочет использовать сомнительные методы.
Ещё я бы не делал пакет internal, а вместо этого сделал package-private классы в том же пакете, чтобы в Java 8 оно не торчало наружу. Package-private именно для этого и существует.