#java
Вопрос:
public <T> T getData(final Class<T> cast, final String query)
{
final Optional<JSONObject> optional = Optional.ofNullable(new JSONObject(getHTTP(query))).filter(s -> s.has("data") amp;amp; s.getJSONArray("data").length() > 0 amp;amp; s.getJSONArray("data").get(0) instanceof JSONObject);
if (optional.isPresent())
{
final JSONObject json = JSONObject.class.cast(optional.get().getJSONArray("data").get(0));
return switch (cast.getSimpleName())
{
case Profile.class -> new Profile(<parameters>);
case UserVideo.class -> new UserVideo(<parameters>);
default -> null;
};
}
return null;
}
Я хочу улучшить этот код и назвать его так
final Profile profile = getData(Profile.class, String.format(URL, "data"))
Проблема в том, что я не могу переключить класс и не хочу использовать строку (так как я хочу расширить свои знания и сделать их более сложными, чем простыми).
Существует ли какой-либо другой способ переключить класс и проанализировать (или даже отразить класс), используя различные параметры, и вернуть его. Учтите, что этот метод может возвращать различные типы классов, и вы предоставляете только ССЫЛКУ и запрошенные данные.
Комментарии:
1. В Java switch-это оператор, а не оператор, поэтому вы не можете использовать его внутри выражения. Вы можете использовать оператор ?: внутри выражения, но это дает вам только два последовательных значения.
2. Ваш комментарий бесполезен, так как я уже это знаю. Я ищу другой подход.
3. Это
switch
кажется неудобным и не очень полезным. Я бы просто вернул методOptional<JSONObject>
(и никогда не возвращал null), и пусть каждый фрагмент вызывающего кода решает, что с ним делать.4. @Christopher Начиная с JEP-361 (Java 14), переключатель также можно использовать в качестве выражения.
5. Отличная новая функция. Спасибо. Мне также нравится расширенная идея instanceof.
Ответ №1:
К сожалению, переключение на java не так мощно, как на других языках. Я думаю, что единственный способ сделать это-через цепочку if-elseif
if (cast == Profile.class) { ... }
else if (cast == UserVideo.class) { ... }
else { return null; }
Но если вы позволите мне перепроектировать API, я предпочитаю:
public JSONObject getData(String query) { ... }
---
profile = Profile.fromJSON(getData(String.format(URL, "data")))
---
class Profile {
static Profile fromJSON(JSONObject json) {
return new Profile(...)
}
}
Редактировать:
Подожди, у меня появилась новая идея
public <T> T getData(Function<JSONObject, T> cast, String query) {
JSONObject json = ...;
return cast.apply(json);
}
profile = getData(Profile::fromJSON, String.format(URL, "data"))
что эквивалентно моему предыдущему ответу, но выглядит немного более похоже на ваш код.
Изменить 2:
Если вам не нравится Profile::FromJSON, вы также можете использовать статическую константу.
static final Function<JSONObject, Profile> PROFILE = json -> new Profile(...);
profile = getData(PROFILE, ...)
Комментарии:
1. В Java 17 появится функция предварительного просмотра JEP-406 Сопоставление шаблонов для switch (Предварительный просмотр) , которая позволит вам сделать что-то подобное с switch.
2. @MarkRotteveel Если я правильно понимаю, сопоставление шаблонов в java работает на основе типа объекта (или структуры), а не идентичности. So
switch (someClass) { case Some.class -> ... }
не поддерживается , потому что он сравниваетa == b
, а неa instanceof B
.