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), но не делает дополнительно то, что может делать (кешировать объекты вне этого интервала. ). Немного поправил статью
Граблями я бы это не назвал. Грабли — это то, что лежит под ногами, на что постоянно наступают новички. Такое как String.equals() и ==. А это — подводные скалы в лагуне мертвых кораблей, куда нормальный моряк соваться никогда не будет.
А вот пример реальных граблей, на которые я наступил на прошлой неделе:
new MessageFormat(«file-{0,date,yyyyMMdd}{1,date,yyyyMMdd}.log»)
.parse(«file-2016020720160208.log»);
А вот пример реальных граблей, на которые я наступил на прошлой неделе:
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) :)
Я в 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-файле для генерации имени для лог-файлов. Проблема обнаружилась, когда нужно было автоматически чистить старые логи: при проверке имени файла на паттерн парсер валился.
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
null
1
2
А вы не могли бы объяснить, что же тут происходит?
тут все подробности: http://stackoverflow.com/a/28148788/1000975
Как-то уныло, конкурс чтецов спецификаций наизусть получился.
Про первое достаточно помнить, что кэш есть и его размер конфигурируем, про остальное — что такое в репозиторий без простыни объяснений «зачем в гамаке и почему стоя на лыжах» попадать не должно.
Про первое достаточно помнить, что кэш есть и его размер конфигурируем, про остальное — что такое в репозиторий без простыни объяснений «зачем в гамаке и почему стоя на лыжах» попадать не должно.
Почему данный код может приводить к deadlock?
synchronized (obj1) {
synchronized (obj2) {
// some code
}
}
Вероятно, тут подразумевается, что если в другом потоке obj1 и obj2 могут захватываться в обратном порядке, то тогда может быть дедлок. Это произойдет если сначала оба потока войдут в свой внешний synchronized (то есть первых захватывает obj1, второй захватывает obj2), а потом оба попытаются войти во внутренний.
Только это не грабля java, а грабля из области concurrency.
Только это не грабля java, а грабля из области concurrency.
Думаю, уместно напомнить о существовании прекрасных статей:
Знаешь ли ты JAVA, %username%?
Знаешь ли ты JAVA, %username%? часть 2
Знаешь ли ты JAVA, %username%?
Знаешь ли ты JAVA, %username%? часть 2
Sign up to leave a comment.
Грабли Java