Действительно ли возможно получить все подклассы класса? [дубликат]

Использование rmtree и воссоздание папки может работать, но я столкнулся с ошибками при удалении и немедленном воссоздании папок на сетевых дисках.

Предлагаемое решение с использованием Walk не работает, так как использует rmtree для удаления папок, а затем может попытаться использовать os.unlink для файлов, которые ранее были в этих папках. Это вызывает ошибку.

Опубликованное решение glob также попытается удалить непустые папки, что приведет к ошибкам.

Я предлагаю вам использовать:

folder_path = '/path/to/folder'
for file_object in os.listdir(folder_path):
    file_object_path = os.path.join(folder_path, file_object)
    if os.path.isfile(file_object_path):
        os.unlink(file_object_path)
    else:
        shutil.rmtree(file_object_path)
17
задан Community 23 May 2017 в 11:51
поделиться

8 ответов

Краткий ответ: нет.

Длинный ответ заключается в том, что подклассы могут возникать разными способами, что в основном делает невозможным их категорический поиск всех.

Вы можете ' Не делайте это во время выполнения, но вы не можете найти классы, пока они не загружены, и как узнать, что они загружены? Вы можете сканировать каждый файл JAR и класса, но это не окончательно. Плюс есть такие вещи, как загрузчики классов URL.

Внутренние классы (статические и нестатические) - еще один случай, который следует рассмотреть. Именованные внутренние классы легче найти. Анонимные внутренние классы потенциально намного труднее найти.

Вы также должны учитывать, что если у класса есть подклассы, то новые подклассы могут быть созданы позже.

24
ответ дан 30 November 2019 в 12:36
поделиться

Я всегда могу создать новый подкласс для любого незавершенного класса, добавить подкласс в путь к классам и победить ваше намерение. Создание подклассов является неограниченным предложением.

Лучшее, что вы можете сделать, это сказать, что для данного пути к классам вы знаете, что такое подклассы, и для этого вам придется сканировать каждый класс в пути к классам.

1
ответ дан 30 November 2019 в 12:36
поделиться

Использовать отражение довольно просто. Прочтите эту статью на сайте JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html

1
ответ дан 30 November 2019 в 12:36
поделиться

Единственный способ сделать это - пройти по иерархии пакетов для пакетов, доступных в пути к классам, проверяя каждый класс с помощью отражения (и это будет отстой, потому что вы эффективно загрузите каждый class, если вы не ограничиваете поиск определенными пакетами).

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

1
ответ дан 30 November 2019 в 12:36
поделиться

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

0
ответ дан 30 November 2019 в 12:36
поделиться

Если вы загружаете классы только с диска или из URL-адресов, вы можете сканировать путь к классам и находить подклассы «вручную».

-2
ответ дан 30 November 2019 в 12:36
поделиться

Вы хотите перечислить классы, реализующие определенный интерфейс, или перечислить классы, которые являются производными от какого-либо базового класса? Это две разные проблемы. И то, и другое, насколько мне известно, будет сложно реализовать, поскольку новые реализации могут быть созданы / установлены на ПК в любое время в будущем. Похоже, вы пытаетесь создать фабричный метод для создания конкретного экземпляра, и вы не хотите жестко кодировать имя класса в коде. Обычно лучше всего использовать конфигурационный файл, в котором перечислены все классы, реализующие интерфейс (или можно использовать базу данных). Поскольку новые классы реализуют интерфейс,

0
ответ дан 30 November 2019 в 12:36
поделиться

вам следует использовать Java ServiceLoader , который является встроенным классом. Он может выполнять итерацию во время выполнения по всем известным реализациям служб (интерфейсов).

Если по какой-то причине он вам не нужен, вы можете использовать ClassLoader.getSystemResources () для перебора всех ресурсов; например, если у вас в 6 раз больше файла /META-INF/com.interface, вы получите 6 итераций.

5
ответ дан 30 November 2019 в 12:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: