Comments 50
>> new URL(«www.yahoo.com»).equals(new URL(«209.191.93.52»))
А это куда он обращается behind-the-scene? В DNS? Неприятный сайд-эффект ИМХО
А это куда он обращается behind-the-scene? В DNS? Неприятный сайд-эффект ИМХО
+4
Это дает весьма интересный эффект. Например, следующий код
выведет:
sse == habr
demitsuri == habr
demitsuri == sse
habr != google
URL в первых трех случаях совпадают, а ресурсы (в контексте расшифровки аббревиатуры URL) — разные.
URL sse = new URL("sse.habrahabr.ru");
URL demitsuri = new URL("demitsuri.habrahabr.ru");
URL habr = new URL("62.213.122.2");
URL google = new URL("google.com");
if(sse.equals(habr))
System.out.println("sse == habr");
else
System.out.println("sse != habr");
if(demitsuri.equals(habr))
System.out.println("demitsuri == habr");
else
System.out.println("demitsuri != habr");
if(demitsuri.equals(sse))
System.out.println("demitsuri == sse");
else
System.out.println("demitsuri != sse");
if(habr.equals(google))
System.out.println("habr == google");
else
System.out.println("habr != google");
* This source code was highlighted with Source Code Highlighter.
выведет:
sse == habr
demitsuri == habr
demitsuri == sse
habr != google
URL в первых трех случаях совпадают, а ресурсы (в контексте расшифровки аббревиатуры URL) — разные.
+1
Да, таки неприятный сайд-эффект, о которм предупреждает FindBugs: invokes java.net.URL.equals(Object), which blocks to do domain name resolution. Полезная тулзовина.
+1
UFO just landed and posted this here
Вообще-то это не сайд-эффект, а специфицированное поведение. Другой вопрос: насколько оно вам нравится или подходит.
0
Хабродебилы не перестают удивлять. Проще нажать минус, чем открыть джавадок?
-1
Основная проблема заключается в том, что URL — локатор ресурса. Т.е. один из его «позывных», образно говоря. И когда на одинаковые (в контексте использования метода equals) «позывные» откликаются разные ресурсы, это уже беда.
+1
Речь о том, что это описанное поводение, оно не должно быть неожиданным. Как и то, что приведенные выше примеры с URL не содержат протокол доступа, и вы получите исключение до первого if.
А по сути проблемы: что ж поделать, придется с этим мириться, использовать альтернативные решения. Хотя бы из-за совместимости, изменять такое поведение не станут.
А по сути проблемы: что ж поделать, придется с этим мириться, использовать альтернативные решения. Хотя бы из-за совместимости, изменять такое поведение не станут.
0
Благодаря этому описанному поведению следующий код
Это описанное (специфицированное) поведение, но от этого оно не менее неинтуитивно и нелогично.
Если метод
bool fun(Object a, Object b) {
return a.equals(b);
}
имеет все шансы выполняться по-разному в зависимости от того, задела уборщица на пару секунд шваброй сетевой кабель, или нет.Это описанное (специфицированное) поведение, но от этого оно не менее неинтуитивно и нелогично.
Если метод
bool isValid(SomeClass x)
в качестве побочного действия переводит объект в бинарную форму и отсылает через сокет на Марс, то это — неинтуитивно, даже если описано. +1
Благодаря этому описанному поведению следующий код
bool fun(Object a, Object b) {
return a.equals(b);
}
имеет все шансы выполняться по-разному в зависимости от того, задела уборщица на пару секунд шваброй сетевой кабель, или нет.
Это описанное (специфицированное) поведение, но от этого оно не менее неинтуитивно и нелогично.
Если метод bool isValid(SomeClass x) в качестве побочного действия переводит объект в бинарную форму и отсылает через сокет на Марс, то это — неинтуитивно, даже если описано.
bool fun(Object a, Object b) {
return a.equals(b);
}
имеет все шансы выполняться по-разному в зависимости от того, задела уборщица на пару секунд шваброй сетевой кабель, или нет.
Это описанное (специфицированное) поведение, но от этого оно не менее неинтуитивно и нелогично.
Если метод bool isValid(SomeClass x) в качестве побочного действия переводит объект в бинарную форму и отсылает через сокет на Марс, то это — неинтуитивно, даже если описано.
0
На самом деле, в примерах выше протокол присутствует, только его съел хаброраспознаватель ссылок.
0
UFO just landed and posted this here
UFO just landed and posted this here
Аналогичное ощущение возникло после прочтения статьи — больше половины описанного я активно использую.
+3
может я не очень крут в русском, и я уже далеко не год программирую на джава. И из всего списка для меня чем-то действительно новым было пересечение в generics типизации. Сама исходная статья даёт отличный рейтинг упущенных вещей при изучении языка. Так например в 10ку попал assert, который я даже не стал упоминать.
Изначально мой как бы «перевод» должен был содержать около 50 пунктов, однако я их перегруппировывал, отсеивал и ленился переводить дальше, в итоге вышло сколько вышло. Хотя материала хватит ещё на несколько частей. Может продолжить?
Изначально мой как бы «перевод» должен был содержать около 50 пунктов, однако я их перегруппировывал, отсеивал и ленился переводить дальше, в итоге вышло сколько вышло. Хотя материала хватит ещё на несколько частей. Может продолжить?
+3
Спасибо за статью, около половины возможностей знал. Во многом узнал благодаря тестам на прохождение сертификации, в реальных проектах стараюсь поменьше использовать такую экзотику, разве что инициализаторы и дженерики, как вполне известные и с трудом заменимые.
+2
UFO just landed and posted this here
Например я рассматриваю ThreadLocal как singleton per thread, если можно так выразиться, и это удобно. Не фонтан конечно, но свою маленькую задачу класс выполняет.
0
мне ThreadLocal очень помог в следующем случае:
я реализовывал Listener класс, у которого было несколько методов onBlaBlaAction(), методы вызываются в строгом порядке. Однако сама библиотека не гарантировала, что все вызовы будут из одного потока. И однажды пришлось добавить поле «состояние» в класс listener. А чтобы потоки его нагло не перетирали — спас ThreadLocal. Синхронизация в этом случае была невозможной.
я реализовывал Listener класс, у которого было несколько методов onBlaBlaAction(), методы вызываются в строгом порядке. Однако сама библиотека не гарантировала, что все вызовы будут из одного потока. И однажды пришлось добавить поле «состояние» в класс listener. А чтобы потоки его нагло не перетирали — спас ThreadLocal. Синхронизация в этом случае была невозможной.
0
UFO just landed and posted this here
Есть популярный метод сравнения объектов — делать проверку классов сравниваемых объектов через равенство классов. По ссылке есть есть пример: DoubleBraceInitialization
Если в классе equals уже определён таким образом, тогда от Вас мало что зависит
Если в классе equals уже определён таким образом, тогда от Вас мало что зависит
0
И всё-таки не стоит писать столь категорично. Я, например, использую double brace для коллекций в тестах, по вашей же ссылке в посте прямо говориться о том, что это нормально работает, что, впрочем, неудивительно :)
0
UFO just landed and posted this here
если бы мне на ревью прислали код с double brace и переопределённым методом equals в этих же двойных скобках — я бы попросил удалить и не позориться
0
UFO just landed and posted this here
ничего плохого в equals для коллекций не вижу. А по поводу equals, переопределяемый в double brace классе — стоит ли овчина выделки? если лаконичность так важна — посмотрите лучше ссылки из статьи:
own-literals-in-java-lists-and-arrays
dollarmaps
google-collections
own-literals-in-java-lists-and-arrays
dollarmaps
google-collections
0
Спасибо! Много нового узнал! По поводу thread dump'а… вот если бы вы сказали способ, как программно сохранить его в файл, было бы совсем круто :)
0
В век eclips'ов и других продвинутых ide — это легко можно сделать во время дебага. в Idea — нажать на pause, затем — Export Threads. А метод описанный в статье больше подойдёт для отлавливания dead-lock'ов на рабочей системе — все равно приложению уже не жить.
0
и ещё один не программный метод — jstack из JDK.
Программно — получить дамп одного треда — Thread.dumpStack(), который вызывает new Exception(«Stack trace»).printStackTrace();
Остаётся получить список всех тредов. Думаю стоит посмотреть на ThreadMXBean из пакета java.lang.management.
Программно — получить дамп одного треда — Thread.dumpStack(), который вызывает new Exception(«Stack trace»).printStackTrace();
Остаётся получить список всех тредов. Думаю стоит посмотреть на ThreadMXBean из пакета java.lang.management.
+2
блин, все же на поверхности: Thread.getAllStackTraces(), видимо ещё сплю
+1
Да, так и сделал в итоге — через ThreadMXBean, только там инфы сильно меньше, чем в оригинальном стэктрейсе. По крайней мере в 1.5. Про переход на 1.6 — то же, что и у вас :) А вот за jstack спасибо большое! Сейчас покопаю, как его можно применить :)
+1
С великой силой, приходит великая ответственность (с) из спайдермена
Если язык позволяет и вы пишите
…
} finally {
return 0;
}
работает принцип «сам дурак». Ворнинг от компилятора вы ведь получили =)
Если язык позволяет и вы пишите
…
} finally {
return 0;
}
работает принцип «сам дурак». Ворнинг от компилятора вы ведь получили =)
0
Почти все что здесь написано(кроме double brace и break label) есть в книгах Core Java vol. 1, 2 Хорстманна и Корнелла (у нас они называются вроде Java 2 том 1, 2).
0
Все уже где-то упоминалось, даже на хабре. А по описанию нетривиальных возможностей лидирует The Java Language Specification. Я и сам не люблю когда меня отсылают к официальной документации, однако здесь не тот случай. Это действительно полезный, упорядоченный источник с хорошими примерами.
0
Прикольно, сам хотел в ближайшее время написать похожую статью.
В довесок к написанному — заметил, что многие не знают:
1. Нормально скомпилируется:
public interface I1 { void m3(); }
public interface I2 { void m3(); }
public class A {public void m3() { } }
public class B extends A implements I1, I2 { }
2. Узнать соответствующий экземпляр внешнего класса из внутреннего можно выражением ИмяВнешнегоКласса.this.
В довесок к написанному — заметил, что многие не знают:
1. Нормально скомпилируется:
public interface I1 { void m3(); }
public interface I2 { void m3(); }
public class A {public void m3() { } }
public class B extends A implements I1, I2 { }
2. Узнать соответствующий экземпляр внешнего класса из внутреннего можно выражением ИмяВнешнегоКласса.this.
0
Only those users with full accounts are able to leave comments. Log in, please.
Нетривиальные возможности Java