Как стать автором
Обновить

Комментарии 14

баги надо устранять не взирая на совместимость. Я так же словил исправление давнего бага с определением user.home при переходе с 7 на 8.
Да, вы правы, добавил ссылку на правку бага. Тут скорее мой косяк, надо лучше читать последние изменения.
Не слышит вас Торвальдс :)
Если вы про этот случай, то коды ошибок и нормальное поведение — это разные вещи. Некорректно спроектированный интерфейс — это не баг. Несоответствие заявленному интерфейсу — вот это баг.
не согласен. Вы просто играете терминологией. Что «баг», а что «не баг» — это вопрос договорённости.

Я сейчас пишу, если что, как человек, который три года в Оракле занимался вопросами соответствия друг другу джавовского поведения и джавовской спеки в самых разных смыслах.
Думаю зависит от частоты использования и ожидания. Если, например, код не срабатывает в 1% случаев, а абсолютное большинство ожидает, что он будет работать по спецификации, то это баг. Если же код срабатывает и уже протестирован для 20% и более случаев, то большинство уже смирилось, что это такая «фича», что, конечно, неприятно, но «баг» остается для обратной совместимости.

Очень интересно поступает Android, который, от targetSdkVersion отменяет «режим обратной совместмости», что приводит к тому, что менять этот targetSdkVersion всегда с опаской. А что на этот раз сломается? Причем заранее определить масштаб трагедии нельзя (
Нет, я про точку зрения Линуса о том, что нельзя фиксить баги, ломая обратную совместимость.
Баг, переживший три релиза, считается фичей (с) Не помню чей :-)…
Общая позиция Java-организации по этому вопросу такая: если есть понятная спецификация, но реализация ей не соответствует, то
1. Баг фиксится в следующей мажорной версии Java
2. Вопрос о бэкпорте в текущую версию и в предыдущие решается путём оценки рисков. Эксперты пытаются методом ленинского прищура оценить, насколько много пользователей пострадает при фиксе этого бага в текущей версии. Если много — фиксить не будут, баг оставят.
3. Вопрос того, как ведут себя в этой ситуации другие реализации Java (IBM, SAP, Azul) — самый интересный. Правильный ответ такой: на их усмотрение. Они должны вести себя либо в точности как спека (для совместимости со стандартом) либо максимально похоже воспроизводить бажное поведение OracleJDK/OpenJDK. Зависит от того, что нужнее их клиентам и им самим.
т.е. исправление этого бага попало под второй пункт? в 8-ке спустя 12 лет исправили, а в предыдущих версиях не стали. В итоге, решать новую проблему, в случае, если на компе несколько версий Java, пришлось с помощью создания хардлинков в ФС
Тут ещё другой момент интересен. Скажем, вы в цикле используете сплит по одному символу (скажем, str.split("=")). Раньше было быстрее прекомпилировать "=" перед циклом (или вообще в статическом поле), и некоторые люди так и делали. Теперь же в несколько раз быстрее выполнять str.split без прекомпиляции, поэтому более оптимальный код для JDK 6 стал менее оптимальным в последующих версиях.

Я лично вообще str.split не люблю за его мутность и медленность регекспов. Какой-нибудь StringUtils из Apache Commons содержит более быстрые и понятные методы. А сплит по одному символу я вообще сам написал, он по скорости в большинстве случаев опережает даже апачевский аналог.

public static @Nonnull String[] split(String string, char delimiter) {
    int n = 1;
    int i = 0;
    while(true) {
        i=string.indexOf(delimiter, i);
        if(i == -1) break;
        n++;
        i++;
    }
    if(n == 1) return new String[] {string};
    
    String[] result = new String[n];
    n = 0;
    i = 0;
    int start = 0;
    while(true) {
        i = string.indexOf(delimiter, start);
        if(i == -1) break;
        result[n++] = string.substring(start, i);
        start = i+1;
    }
    result[n] = string.substring(start);
    return result;
}


Почему-то никто не хотел два раза проходить по строке, а все хотели создавать динамический ArrayList. А два прохода почти всегда быстрее.
По одному символу есть старый добрый StringTokenizer
Весь первый цикл вместе с переменной i можно выбросить, заменив простым подсчетом:
for (int i = 0; i < string.length(); i++) {
    if (string.charAt(i) == delimiter) {
        n++;
    }
}
Вы, конечно, попробовали реализовать своё решение и замерили производительность? Я вот такой вариант пробовал, он медленнее на большинстве реальных строк (если они не сплошь из разделителей состоят). Каждый вызов charAt проверяет границы, так что у вас будет больше проверок. Разумеется, если б это писали авторы JDK прямо в классе java/lang/String, они бы вообще не вызывали ни indexOf, ни charAt, а доставали символы из массива. Но я не могу позволить себе такую роскошь.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории