Как передать 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