Ограничения байт-кода JVM для взаимодействия классов классов

Я просматривал инструкции JVM bytecode и был удивлен, увидев, что все взаимодействия между классами (например, casting, new и т.д.).) полагаются на постоянный поиск в пул для идентичности других классов.

Правильно ли вы заключаете, что это означает, что один класс не может знать о существовании более чем 64 тыс. других, поскольку их невозможно ссылаться? Если нужно было сослаться на это много, что нужно делать - делегировать работу нескольким классам, каждый из которых может иметь свои собственные < 64k взаимодействия?

(Причина, по которой это меня интересует, заключается в том, что у меня есть привычка писать генераторы кода, иногда производя тысячи различных классов, и что некоторые языки (например, Scala) создают классы в избытке. Поэтому кажется, что если true, будьте осторожны: если у меня есть сотни методов в классе, каждый из которых использует сотни (отдельных) классов, я мог бы превысить пространство с постоянным пулом.)

Ответы

Ответ 1

Правильно ли вы заключаете, что это означает, что один класс не может знать о существовании более чем 64 тыс. других, так как с ними невозможно ссылаться?

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

Если нужно было сослаться на это много, что нужно делать - делегировать работу нескольким классам, каждый из которых может иметь свои собственные < 64k взаимодействия?

Я так думаю.

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

Ответ 2

Похоже, ваша проблема может быть решена с помощью invokedynamic. Это в основном гораздо более быстрая форма отражения, предназначенная для облегчения реализации динамических языков в JVM.

Если вам действительно нужно иметь дело с тысячами автоматически генерируемых классов, вы, вероятно, не хотите статически связывать все это. Просто используйте invokedynamic. Это также имеет то преимущество, что позволяет отложить некоторое генерирование кода до времени выполнения.

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