Pull to refresh

Comments 15

В первом вопросе ответ не совсем верный. Зависит от java.lang.Integer.IntegerCache.high.

Наша JVM, строго следуя спецификации, в первых трех случаях возвращает один и тот же объект для обеих частей равенства, а в последнем — два разных.
По документации:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
Спасибо за поправку. Не совсем верно написал. Наша JVM делает то, что должна (кеширует объекты для интервала -128..127), но не делает дополнительно то, что может делать (кешировать объекты вне этого интервала. ). Немного поправил статью
Верхняя граница интервала для кеширования задаётся property

-Djava.lang.Integer.IntegerCache.high=size

Или с помощью аргумента JVM

-XX:AutoBoxCacheMax=size
Граблями я бы это не назвал. Грабли — это то, что лежит под ногами, на что постоянно наступают новички. Такое как String.equals() и ==. А это — подводные скалы в лагуне мертвых кораблей, куда нормальный моряк соваться никогда не будет.
А вот пример реальных граблей, на которые я наступил на прошлой неделе:

new MessageFormat(«file-{0,date,yyyyMMdd}{1,date,yyyyMMdd}.log»)
.parse(«file-2016020720160208.log»);
Ну рассказывайте уже, в чем подвох.
Я в MF не силен, но проверил — вызов кидает parse error.

У нас тут свои грабли были с форматом даты:
new SimpleDateFormat("YYYY-MM-DD hh:mm:ss") работало до тех пор, пока не включили setLenient(false) :)
В документации же в простой и доходчивой форме написано:
MessageFormat uses patterns of the following form:
MessageFormatPattern:
String
MessageFormatPattern FormatElement String
То есть, как легко заметить даже невооруженным взглядом, FormatElement должен быть отделен от другого FormatElement-а как минимум String. К сожалению, разработчики забыли упомянуть что такое этот 'String'. Но тут даже ребенку ясно, что это любая непустая строка, и что "" не может являться 'String'-ом. Как-то так. Кроме того, данный паттерн успешно работает в обратную сторону — на .format() и генерирует правильную строку.

Этот паттерн у меня прописан в config-файле для генерации имени для лог-файлов. Проблема обнаружилась, когда нужно было автоматически чистить старые логи: при проверке имени файла на паттерн парсер валился.
Вот мой любимый пример:

class A {
    final static Object b = new B();
    final static int S1 = 1;
    final static Integer S2 = 2;

    static void f() {
        System.out.println(S1);
        System.out.println(S2);
    }
}

class B {
    static {
        A.f();
    }
}

public class App
{
    public static void main( String[] args )
    {
        A.f();
    }
}

результат
1
null
1
2

А вы не могли бы объяснить, что же тут происходит?
Как-то уныло, конкурс чтецов спецификаций наизусть получился.
Про первое достаточно помнить, что кэш есть и его размер конфигурируем, про остальное — что такое в репозиторий без простыни объяснений «зачем в гамаке и почему стоя на лыжах» попадать не должно.
Почему данный код может приводить к deadlock?
synchronized (obj1) {
                synchronized (obj2) {
                    // some code
                }
            }
Вероятно, тут подразумевается, что если в другом потоке obj1 и obj2 могут захватываться в обратном порядке, то тогда может быть дедлок. Это произойдет если сначала оба потока войдут в свой внешний synchronized (то есть первых захватывает obj1, второй захватывает obj2), а потом оба попытаются войти во внутренний.

Только это не грабля java, а грабля из области concurrency.
Sign up to leave a comment.