Операция «K». Ищем баги в коде IntelliJ IDEA
В этой статье мы проверим проект IntelliJ IDEA Community Edition на наличие ошибок и отправим наши правки разработчикам. Крупный проект, Open Source база и использование статического анализатора при разработке. Сложная задача для PVS-Studio.
https://habr.com/ru/companies/pvs-studio/articles/780560/
👉@BookJava
В этой статье мы проверим проект IntelliJ IDEA Community Edition на наличие ошибок и отправим наши правки разработчикам. Крупный проект, Open Source база и использование статического анализатора при разработке. Сложная задача для PVS-Studio.
https://habr.com/ru/companies/pvs-studio/articles/780560/
👉@BookJava
👍3🤮2💩2
Как разбить строку на слова?
StringTokenizer – специально предназначенный для этого класс стандартной библиотеки Java. Ему нужно задать разделители, по ним строка будет разделена на «токены». Это устаревший класс, он остается в библиотеке только для обратной совместимости.
Вместо него рекомендуется использовать метод
Другой подходящий метод –
👉@BookJava
StringTokenizer – специально предназначенный для этого класс стандартной библиотеки Java. Ему нужно задать разделители, по ним строка будет разделена на «токены». Это устаревший класс, он остается в библиотеке только для обратной совместимости.
Вместо него рекомендуется использовать метод
String.split()
. Метод принимает строку с регулярным выражением, и опциональный лимит токенов. Реализация особенно оптимизирована для односимвольного разделителя. Но следует помнить, что даже если символ один, это всё ещё регулярное выражение – спецсимвол должен экранироваться.Другой подходящий метод –
Pattern.split()
. Он, наоборот, вызывается у регулярного выражения, а принимает целевую строку. В этот же метод делегируется и выполнение String.split()
. Этот способ предпочтительнее, когда в регулярном выражении больше одного символа, а скомпилированный паттерн применяется повторно.👉@BookJava
👍5❤2🥰1
Как передать runtime информацию о generic-типе?
Когда вы проектируете API-метод библиотеки, иногда логика его реализации может зависеть от указанного клиентом типа. Особенно часто с этой задачей встречаются при разработке парсеров. Например, библиотека Jackson превращает JSON в объект заданного класса. На интервью этот вопрос можно встретить в виде практической задачи.
Первое, что приходит в голову для решения – дженерик-параметр. Такой подход не сработает, потому что тип будет стёрт во время компиляции, а логика будет происходить позже, во время выполнения.
Решение, которое сработает для многих случаев – объявление в методе аргумента типа
На помощь приходит техника, описанная в предыдущей публикации.
1. Объявляется generic класс-обертка над типом:
2. В обертку добавляется конструктор с видимостью protected. Теперь можно создавать объекты только наследников, но не самого этого типа.
3. Пользователь будет передавать экземпляр анонимного наследника обертки: new
4. Внутри вызов
👉@BookJava
Когда вы проектируете API-метод библиотеки, иногда логика его реализации может зависеть от указанного клиентом типа. Особенно часто с этой задачей встречаются при разработке парсеров. Например, библиотека Jackson превращает JSON в объект заданного класса. На интервью этот вопрос можно встретить в виде практической задачи.
Первое, что приходит в голову для решения – дженерик-параметр. Такой подход не сработает, потому что тип будет стёрт во время компиляции, а логика будет происходить позже, во время выполнения.
Решение, которое сработает для многих случаев – объявление в методе аргумента типа
Class<T>
. Пользователь будет передавать в него значение Foo.class
или fooInstance.getClass()
. Проблемы с ним начинаются, когда становится нужно передать generic-тип. Синтаксис .class
не поддерживает дженерики, а .getClass()
от экземпляров List<String>
и List<Integer>
вернет один и тот же объект-описание сырого типа List.На помощь приходит техника, описанная в предыдущей публикации.
1. Объявляется generic класс-обертка над типом:
TypeInformation<T>
;. Наш метод будет принимать информацию о типе в виде экземпляра этой обертки.2. В обертку добавляется конструктор с видимостью protected. Теперь можно создавать объекты только наследников, но не самого этого типа.
3. Пользователь будет передавать экземпляр анонимного наследника обертки: new
TypeInformation<List<String>>() {}
.4. Внутри вызов
getClass().getGenericSuperclass()
вернет ParameterizedType
. Это будет описание типа родителя анонима, то есть самой обертки. Из него с помощью getActualTypeArguments()
можно достать рантайм-информацию о значении дженерика (о List<String>).👉@BookJava
👍8
Как использовать JavaEE сервлет в Spring Framework?
Web-приложение на Spring MVC технически само по себе работает на сервлетах: всю обработку запросов берет на себя единый
Если вам нужно определить в программе полностью независимый от Spring-контекста сервлет или фильтр, ничего особенного для этого делать не нужно. Как обычно в Servlet API, нужно объявить класс, добавить его в web.xml как сервлет, добавить для сервлета маппинг.
Сервлет живет вне Spring-контекста, внедрение зависимостей в нём просто так не заработает. Чтобы использовать autowiring, на этапе инициализации сервлета вызывается статический
Если программа построена на Spring Boot, создание бина типа
👉@BookJava
Web-приложение на Spring MVC технически само по себе работает на сервлетах: всю обработку запросов берет на себя единый
DispatcherServlet
. С его помощью реализуется паттерн Front Controller.Если вам нужно определить в программе полностью независимый от Spring-контекста сервлет или фильтр, ничего особенного для этого делать не нужно. Как обычно в Servlet API, нужно объявить класс, добавить его в web.xml как сервлет, добавить для сервлета маппинг.
Сервлет живет вне Spring-контекста, внедрение зависимостей в нём просто так не заработает. Чтобы использовать autowiring, на этапе инициализации сервлета вызывается статический
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext
, с текущим сервлетом и его контекстом в аргументах. В этом же утилитарном классе есть ряд других средств для работы с контекстом извне.Если программа построена на Spring Boot, создание бина типа
ServletRegistrationBean
поможет добавить сервлеты в рантайме. А для декларативного добавления на этапе компиляции, к классу конфигурации применяется @ServletComponentScan
. С этой аннотацией стартер приложения просканирует и добавит в контекст все web-компоненты в стиле Servlet 3.0: классы с аннотациями @WebFilter
, @WebListener
и @WebServlet
.👉@BookJava
👍5🎉2
This media is not supported in your browser
VIEW IN TELEGRAM
Как работает память Java?
Прежде чем мы перейдем к вопросам производительности, нам нужно узнать, что на самом деле происходит в фоновом режиме JVM (Java Virtual Machine). Это отправная точка для каждого разработчика, который хочет изучить и настроить производительность, чтобы набрать скорость. Итак, давайте погрузимся в мир кодов.
В Java управление памятью осуществляется JVM автоматически для хранения ваших переменных, классов, полей и так далее... Первое, что мы узнаем, это то, что в JVM память разделена на две области. Одна из них называется Stack, а другая - Heap.
https://blog.stackademic.com/how-java-memory-works-c751460e3cbd
👉@BookJava
Прежде чем мы перейдем к вопросам производительности, нам нужно узнать, что на самом деле происходит в фоновом режиме JVM (Java Virtual Machine). Это отправная точка для каждого разработчика, который хочет изучить и настроить производительность, чтобы набрать скорость. Итак, давайте погрузимся в мир кодов.
В Java управление памятью осуществляется JVM автоматически для хранения ваших переменных, классов, полей и так далее... Первое, что мы узнаем, это то, что в JVM память разделена на две области. Одна из них называется Stack, а другая - Heap.
https://blog.stackademic.com/how-java-memory-works-c751460e3cbd
👉@BookJava
👍4❤1🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Уроки Java для начинающих
#1 — Установка JDK и IDE
#2 — Переменные. Примитивные типы данных
#3 — Строки (String). Ссылочные типы данных
#4 — Условные конструкции (if-else, switch-case)
#5 — Цикл for
#6— Циклы While и Do While
#7 — Консольный ввод данных
#8 — Массивы
#9 — Многомерные массивы
#10 — Классы и объекты
источник
👉@BookJava
#1 — Установка JDK и IDE
#2 — Переменные. Примитивные типы данных
#3 — Строки (String). Ссылочные типы данных
#4 — Условные конструкции (if-else, switch-case)
#5 — Цикл for
#6— Циклы While и Do While
#7 — Консольный ввод данных
#8 — Массивы
#9 — Многомерные массивы
#10 — Классы и объекты
источник
👉@BookJava
👍5
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
👍4