Может ли кто-нибудь объяснить эту функцию, которую я случайно написал (ключевое слово Any)?

Я пишу небольшое Java-приложение, которое использует сериализацию/десериализацию для сохранения/загрузки ArrayLists. Я написал следующую функцию, которая принимает путь к файлу и десериализует объекты внутри него:

private Object deserialize(String fileName)
            throws IOException, ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
            return ois.readObject();
        }
}

Поскольку эта функция возвращает тип объекта, мне пришлось бы привести его к ArrayList следующим образом:

ArrayList<String> arrayList = (ArrayList<String>)deserialize("test.file");

(Строка выше должна быть окружена оператором try/catch, но я не включил его сюда для удобочитаемости)

Этот процесс отлично сработал для меня, однако я хотел попробовать и посмотреть, смогу ли я отредактировать код так, чтобы мне не пришлось самостоятельно приводить объект, и поэтому я в шутку набрал Любой в качестве возвращаемого типа моего функция, и компилятор не жаловался. Затем я изменил свою функцию на следующую, и, к моему удивлению, она действительно сработала!

private <Any> Any deserialize(String fileName)
            throws IOException, ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
            return (Any)ois.readObject();
        }
}

При использовании этой функции мне больше не нужно приводить возвращаемое значение к ArrayList, и вместо этого я могу просто использовать:

ArrayList<String> arrayList = deserialize("test.file");

Часть меня хочет просто смириться со всем этим и просто использовать функцию, не задаваясь вопросом, как она работает, но я знаю, что у меня будут проблемы с этим.

Может кто-нибудь объяснить, почему эта функция работает именно так, или перефразируя, просто объясните ключевое слово Любой, поскольку я, честно говоря, никогда раньше его не видел.

Any здесь просто переменная универсального типа, а не ключевое слово. Это ничем не отличается от того, если бы вы использовали T, V, RESULT или что-то еще. Другими словами, вы сделали метод универсальным и выполнили приведение в месте вызова скрытый.
Slaw 10.07.2019 18:04

Но это всегда будет работать только в том случае, если предполагаемый тип на месте вызова — Object. В противном случае вы можете получить ClassCastException, если читаемый объект не относится к предполагаемому типу.

Andy Turner 10.07.2019 18:05

См. errorprone.info/bugpattern/TypeParameterUnusedInFormals для объяснения того, почему такое использование дженериков не такая уж хорошая идея.

Andy Turner 10.07.2019 18:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Any не является ключевым словом в Java. Главное, на что следует обратить внимание, — это <Any> после модификатора доступа. Это общая спецификация метода — метод обобщается с помощью параметра типа с именем Any (который вы затем используете для приведения в теле метода), и когда вы вызываете метод, Java будет сделать вывод о возвращаемом типе.

Но ничего особенного в слове «Любой» нет. Вы могли бы использовать «T», «SomeType» или даже «SpongeBob» для того же эффекта.

Плюс 1 для Губки Боба

Robert Kock 10.07.2019 18:11

А, это имеет смысл. Я знаком с дженериками, но у меня не было надлежащего мышления, чтобы понять, что «любой» был параметром, и вместо этого считал, что это ключевое слово. Я полагаю, это объясняет, почему я не смог найти никакой документации по ключевому слову «Любой», потому что его даже не существует!

HomeworkHopper 10.07.2019 18:21

Другие вопросы по теме