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

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

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

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

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

8 ответов

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

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

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

РЕДАКТИРОВАТЬ: Чтобы быть конкретным, вы не можете "импортировать" оба. Но вы можете получить доступ к обоим во время выполнения.

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

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

Я сделал демонстрацию этого на github!

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

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

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

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

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

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

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

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

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