2013-06-28 5 views
1

У меня проблема в моем проекте Java, у меня есть куча проектов (например, A, B, C ...), которые имеют класс Tools в папке с инструментом в пути, таком как src.tool.Tools, один и тот же путь и одно и то же имя класса для всех них.Вызвать функцию с тем же именем, что и другая функция с тем же именем пакета

Теперь у меня есть проект Z, который имеет в своем пути построения все эти проекты (A, B, C ...). Как я могу убедиться, что при импорте одного класса инструмента я импортирую тот, который мне действительно нужен?

Сложнее, если в A.Tool У меня есть метод, такой как public int tool() {return 1} и в B.Tool другой метод, такой как public int tool() {return 0}. Как я могу убедиться Я называю функцию, которую я действительно хочу?

Спасибо за все!

+0

Я не думаю, что вы можете управлять с помощью класса. Это определяется порядком файлов jar в пути к классу. (Будет использоваться первый файл jar, который предоставляет класс.) – aioobe

+0

Вам нужно убедиться, что имена пакетов уникальны, например 'a.tool',' b.tool' и т. Д., Вместо того, чтобы иметь одинаковое имя пакета в каждом проект. –

+1

Кажется, это очень плохой дизайн, который приводит к методам (а не к функциям), имеющим *** точно *** одно и то же имя. Вы должны посмотреть, чтобы переименовать их с лучшими именами, а не всеми этими махинациями. –

ответ

3

Три варианта:

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

Сложный способ:: Создайте загрузчики классов для каждого проекта, на который вы зависите, и загрузите этот класс для конкретного класса. Это большая работа, чтобы получить право, вы можете использовать OSGI для этого. Сделайте это, только если ваша главная цель - узнать о загрузчиках классов.

Простой и правильный способ: Реорганизовать ваши проекты, чтобы все пакеты в каждом проекте имели название проекта (или некоторое его представление) в названии пакета. Это делает каждое имя пакета уникальным, и вы можете без проблем получать доступ к классам (возможно, используя полное имя класса, если вам нужно использовать несколько классов инструментов в одном месте). В то время как вы на нем, вы можете также переименовать классы инструмента, которые на самом деле описывает цели, имена классов и пакетов, такие как «Util», «Tool» или «Misc», действительно сильно пахнут кодом.

+0

Кажется, что рефакторинг - это простой, как самый элегантный способ решить эту проблему, что он не подвержен многим головным болям в будущем. Благодаря! – Random

0

Предполагая, что ваши проекты A, B, C имеют разные пространства имен пакетов, например. com.you.A, com.you.B и т. д., ваш класс Tools теперь будет доступен в нескольких местах, таких как com.you.A.tool.Tools, com.you.B.tool.Tools и т. д.

Итак, когда в проекте Z вы создаете экземпляр класса «Инструменты», вы можете указать точный класс для использования при объявлении ссылочной переменной объекта.

private com.you.A.tool.Tools toolsFromA; 
private com.you.B.tool.Tools toolsFromB; 

вызов toolsFromA.tool() возвращает 1 и вызов toolsFromB.tool() возвратит 0.

+0

Извините за мое плохое письмо Я недостаточно объяснил себя. Проблема в том, что они имеют одинаковое пространство имен пакетов. Например, в Jar AI есть com.you.tool.Tools и в Jar BI есть com.you.tool.Tools – Random

+0

_Assuming, что ваши проекты A, B, C имеют разные пространства имен пакетов. Ну, ** они не ** – BackSlash

1

Вероятно, с помощью user-defined class loader: Каждого загрузчика классов определяемого пользователя

является экземпляром подкласса абстрактных класс ClassLoader. Приложения используют пользовательский класс загрузчиков, чтобы расширить способ динамической загрузки Java Virtual и тем самым создает классы. Пользовательские загрузчики классов могут использоваться для создания классов, которые исходят от пользовательских источников. Например, класс может быть загружен через в сеть, созданную «на лету» или извлеченную из зашифрованного файла.

+0

Ничего себе! это тонна документации. Благодаря! – Random

1

Я не думаю, что можно делать то, что вы хотите. Если у вас есть три класса, все называемые «src.tool.Tools», Java не волнует, какой файл jar вы загрузили из него. Если все три проекта (которые я предполагаю, например, файлы jar) имеют этот же класс, у Java будет столкновение, и вы не можете предсказать, какие инструменты он будет загружать.

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

Существует проблема с решением проблемы. Вы можете создать новый ClassLoader для каждого проекта и спросить ClassLoader для желаемого проекта для класса Tools. Затем, используя отражение, вы можете создать экземпляр и вызвать метод. Поскольку каждый проект находится в своем классе ClassLoader, три класса инструментов больше не будут сталкиваться.

Ex:

URLClassLoader a = new URLClassLoader(aJar.toURL(), getClass().getClassLoader()); 
Class toolsClass = Class.forName("src.tool.Tools", true, a); 
Method m = toolsClass.getDeclaredMethod("tool"); 
Object i = toolsClass.newInstance(); 
Object result = m.invoke(instance); 

(URLClassLoader пример вытащил из How should I load Jars dynamically at runtime?)

+0

Да, вы правы, проект означает банку. Извините за плохое имя, о котором я думал в терминах eclipse. – Random