I used to be an adventurer like you, then I dereferenced NULL pointer
I used to be an adventurer like you, then I dereferenced NULL pointer
Просыпаешься в шаббат с мыслью заняться чем-нибудь бесполезным, но дрочащим ЧСВ.
Решаешь позадрачивать код кавераж на юнит-тестах.
Находишь опечатку в коде, доволен собой.
Удаляешь ненужный код. Снова доволен собой.
Решаешь покрыть тестом вот это вот условие.
ДВА ЧАСА ЕБЁШЬСЯ РАЗБИРАЯСЬ С ВЫЯВЛЕННОЙ ПРОБЛЕМОЙ.
РАЗОБРАВШИСЬ, ПОНИМАЕШЬ, ЧТО ПРОБЛЕМА НЕ АКТУАЛЬНА НА ПРОДАКШЕНЕ
позавчера вышла tika-1.9 наконец-то умеет толком извлекать всякую метаинфу из видеофайлов
tfw кто-то в 2017 году всё ещё использует Closeable объекты вне try-with-resources
public class AsyncLock
Можно было бы поставить тег */b/ если бы я это в репозиторий не запушил
Это чувство, когда JVM от IBM считает себя умнее тебя и приходится идти на ухищрения дабы его наебать и сэкономить памяти на долгоживущих строках:
$ cat Main.java
import java.lang.reflect.Field;
public class Main {
public static void main(final String... args) throws Exception {
Field f = String.class.getDeclaredField("value");
f.setAccessible(true);
StringBuilder sb = new StringBuilder(40);
sb.append("01234567890123456789012345");
String s1 = sb.toString();
sb.append("hello, world!");
String s2 = sb.toString();
Object v1 = f.get(s1);
Object v2 = f.get(s2);
System.out.println(v1 == v2);
}
}
$ javac Main.java
$ java Main
false
$ /opt/ibm/java-x86_64-80/bin/java Main
true
Собрал пакет отдал в тестирование.
Опередил тестировщиков, написал ещё кучу функционала, собрал новую версию пакета и отдал в тестирование.
Снова опередил тестировщиков, нашёл у себя багу стал готовить фикс.
Опередил самого себя и обнаружив, что бага — фича. Кажется.
Такая неделя.
protected Members:If members are declared as protected then these are accessible to all classes in the package and to all subclasses of its class in any package where this class is visible.
tfw программа указывает тебе на ошибки в твоём коде
интересная статья как в джаве вызвать незаоверрайженный метод родительского класса не из наследного класса: http://javachannel.org/posts/bypassing-subclass-method-overrides/
бывают дни, когда за один день с нуля целиком реализуешь какую-то нетривиальную фичу. ложишься спать довольным собой, но утром просыпаешься с пустой головой и отсутствием желания что-то делать. как побыстрее восполнить потраченные ресурсы мозга?
оказалось, что joda-time изкоробки нет метода у DateTimeFormatter, который бы максимальное быстро распарсил из строки столько сколько нужно, и вернул количество символов, на которое нужно отступить
У меня вопрос, но начну с введение в то как я до него дошёл.
Допустим, у нас есть какой-то коллбэк, в качестве примера возьмём FutureCallback из всячески уважаемой мной библиотеки HttpCore.
Допустим также, что мы угорели по асинхронности и поэтому после того как коллбэк завершил свою работу, мы хотим сообщить об этом куда следует. Например, чтобы там новый запрос запустили или ещё чего.
Наивная имплементация будет выглядеть примерно так:
public class CompletingFutureCallback<T> implements FutureCallback {
private final FutureCallback<? super T> callback;
private final Runnable completionCallback;
public CompletionFutureCallback(
final FutureCallback<? super T> callback,
final Runnable completionCallback)
{
this.callback = callback;
this.completionCallback = completionCallback;
}
@Override
public void cancelled() {
callback.cancelled();
completionCallback.run();
}
@Override
public void completed(final T result) {
callback.completed(result);
completionCallback.run();
}
@Override
public void failed(final Exception e) {
callback.failed(e);
completionCallback.run();
}
}
Зоркий глаз сразу скажет: А что если коллбэк был написан говнокодером и он кинет unchecked exception в ответ на вызов cancelled
, completed
или failed
? Тогда completionCallback
вызван не будет. Ладно, переделаем на finally
. Далее уже рассматриваем рефакторинг одной функции, благо все они однотипные:
@Override
public void cancelled() {
try {
callback.cancelled();
} finally {
completionCallback.run();
}
}
Зоркий глаз возразит ещё раз: А что если оба коллбэка написаны одним и тем же говнокодером и completionCallback.run()
так же кинет unchecked exception? Да, после того как unchecked exception кинул callback.cancelled()
. Даже если мы где-то снаружи ловим все Throwable, то информация о первом эксепшене будет безвозвратно потеряна.
В этот момент перфекционист вырывает клок волос из головы и призывает в помощь try-with-resources:
class Completer implements AutoCloseable {
private final Runnable completionCallback;
public Completer(final Runnable completionCallback) {
this.completionCallback = completionCallback;
}
@Override
public void close() {
completionCallback.run();
}
}
public class CompletingFutureCallback<T> implements FutureCallback<T> {
…
@Override
public void cancelled() {
try (Completer completer = new Completer(completionCallback)) {
callback.cancelled();
}
}
…
}
Вот теперь всё предельно корректно:
Если callback
кинет исключение, то completer.close()
так же будет вызван, и если он также кинет исключение, то это второе исключение будет добавлено к первому в список suppressed и при печати стек-трейса его будет видно и можно будет поанализировать.
Ну а если callback
отработал как следует, то completer.close()
так же будет вызван, а если исключение, if any, будет также проброшено наружу.
Посоветуйте годную гуглгруппу или иной ресурс, куда можно было бы запостить
пост со сравнением двух сходных идиом и чтобы получить нормальную дискуссию.
SO не подходит, потому что у меня скорее не вопрос, а приглашение к обсуждению.
В гуглгруппсы глянул и их там сотни и первые две на полнены вопросами типа
how to hide and show cursor in JTextField? и происками HR
ну давай по пунктам разберём по ссылке написанное) складывается ощущение что авторы по жизни обиженные, про таких говорят что Брин не хотел, а Пэйдж не старался))
When you add a throw statement to an existing function, you must examine all of its transitive callers.
Ничего не должен, потому что для checked exceptions компилятор сам скажет, где эксепшен забыли обработать или пробросить
functions may return in places you don't expect
Тупо похуй где они вернут, главное что. И в случае checked exceptions явно указывается какие исключения могут возникнуть в конкретной функции
Lots of supporting machinery is needed to make writing correct exception-safe code easy.
Какая разница, где чистить ресурсы в goto statement или в finally? Только checked exceptions и try-with-resources делают многие вещи автоматическими
Turning on exceptions adds data to each binary produced, increasing compile time (probably slightly) and possibly increasing address space pressure.
Пиздёж без пруфов и бенчмарков
For example, invalid user input should not cause exceptions to be thrown
Вот это вообще пушка. Какая им разница, как парсер запроса сообщит наружу об ошибке? Это уже приблуда, которая response генерит пусть перехватить эксепшен и сообщит юзеру, что он мудак. А во внутренние дела парсера пусть не лезет. Эксепшены как раз и прудуманы для того чтобы делегировать обработку ошибок кому надо.
В общем, тебе нужно много думать о своём поведении, стремиться к пробуждению сознания)
http://docs.oracle.com/javase/8/docs/api/java/nio/file/DirectoryStream.html:
If an I/O error is encountered when accessing the directory then it causes the Iterator's hasNext or next methods to throw DirectoryIteratorException with the IOException as the cause.
public final class DirectoryIteratorException extends ConcurrentModificationException
Пиздец, блядь. «У нас какая-то хуйня случилась при итерировании по директории!» — «Кидай RuntimeException, чтобы программер заебался дебажить!»
Вот натурально, давно требуется уже интерфейс который бы позволял итерирование, но мог кинуть эксепшен в процессе. Казалось бы — один новый интерфейс и небольшая поправка в JLS. Но нет! Мы будет маскировать IOException под RuntimeException.
Как лямбды вводить — так пожалуйста, а как что-то реально полезное сделать — жрите говно @ наступайте на грабли.
http://ideone.com/MB7biY sapienti sat
В классе java.nio.file.Files присутствуют две статические функции для создания директорий:
createDirectory(Path, FileAttributes...)
createDirectories(Path, FileAttributes...)
Активным пользователям mkdir(1)
даже не нужно читать доку чтобы знать особенности различия:
Первая создаёт одну папку и ругается если она уже есть.
Вторая создаёт все нужные папки и не ругается если папка уже есть.
В общем, мне было очень приятно обнаружить такую преемственность на уровне флага -p
.
пооптимизячил один класс. теперь вся jvm может схлопнуться с сегфолтом, если неправильно использовать класс в однопоточном приложении