Можно использовать два класса Java с одинаковым именем и одним пакетом?

Можно ли импортировать и использовать два разных класса с тем же именем и пакетом в java?

Например, допустим, что у меня есть два класса с именем "com.foo.Bar", которые немного отличаются. Я хотел бы иметь возможность использовать оба варианта, но у меня есть ограничение (из-за глупого рефлексивного дерьма), которое заставляет меня сохранять имена и пакеты одинаковыми.

Есть ли какая-то особенность java, которая позволила бы мне импортировать и изолировать каждый из этих классов?

Чтобы разработать, я изменил схемы Avro так, чтобы их никогда не изменяли (oops!), и теперь я хотел бы вернуться и изменить старые файлы avro, которые невозможно прочитать с помощью моего нового схему в файлы, которые могут быть прочитаны моей новой схемой. Кажется, что Avro заставляет вас использовать определенный класс и имя пакета для загрузки файлов.

Ответ 1

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

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

Однако это звучит как НЕВЕРОЯТНАЯ плохая идея. Я вернусь и найду другой способ решить вашу проблему. Это в конечном итоге приведет вас к сердечной боли. Похоже, это уже есть, когда вы исследуете загрузчики классов.

EDIT: Чтобы быть конкретным, вы не можете "импортировать" оба. Но вы можете получить доступ к ним во время выполнения.

Ответ 2

Нет, пакеты java используются точно, чтобы избежать этой проблемы.

Ответ 3

Да, это так. Это требует, чтобы вы создали свой собственный ClassLoader, хотя

Я сделал демо этого на github до!

Ответ 4

В Java нет пространств имен, только в С#, поэтому я предполагаю, что вы имеете в виду пакеты. В проекте может быть только одно полное имя.

Ответ 5

Технически это можно сделать, используя некоторые низкоуровневые трюки, такие как переписывание кода байтового уровня. Насколько я знаю, разные java crypter/encrypters работают так: у них много классов под названием A.class B.class C.class и т.д.

Ответ 6

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

Это не то, как работает Java, и это не допускается специально - вы не должны делать глупые вещи, которые могут испортить вам вещи.

Ответ 7

Мне кажется, что вам нужно определить сигнатуры вашего метода в интерфейсе com.foo.Bar. Затем укажите две различные конкретные реализации интерфейса (скажем, com.foo.DefaultBar и com.foo.SpecialBar). Таким образом, вы можете запрограммировать тип интерфейса и переключаться между двумя различными реализациями по мере необходимости.

Можете ли вы рассказать о том, что вы подразумеваете под "рефлексивным дерьмом"? Это может обеспечить понимание вашей точной проблемы.

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

Ответ 8

Как уже упоминалось, вы пишете свой собственный загрузчик классов или дополнительно используете инфраструктуру OSGi, такую ​​как Equinox, которая делает загрузку классов для вас