Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по рефлексии в Java 
:(
    Опции темы
koreyko
Дата 7.9.2015, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 20.4.2010

Репутация: нет
Всего: нет



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

Вкратце, надо считать некоторые данные с серверов. ПО на этих серверах может быть разных версий, соответственно у каждой версии свои названия полей данных. Мне надо на этапе выполнения определить версию сервера и подставить в запросе соответствующие имена данных. Я никогда не использовал рефлексию, здесь решил попробовать, т.к. вроде бы она позволяет решить задачу. 

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

Получилось что-то типа этого:

Код

class Server {
}

class Server123 extends Server {

// данные для сервера версии 123
}

class Server456 extends Server {

// данные для сервера версии 456
}


Далее в точке вызова я получаю версию сервера и создаю объект соответствующего дочернего класса с помощью рекфлексии:

Код

Class c = Class.forName("Server"+"123");    
Object obj = c.newInstance(); 


Теперь мне нужно объект obj привести к типу Server123. Здесь у меня происходит затык или с синтаксисом или с пониманием всего процесса.

Вроде бы надо написать как-то так:

Код

Server server = (Server123) obj;


Но как правильно синтаксически указать тип Server123 (т.е. то, что в скобках), если он мне не известен на этапе компиляции?

Заранее спасибо за помощь!


PM MAIL   Вверх
jManiak
Дата 7.9.2015, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 6.2.2007
Где: Санкт-Петербург

Репутация: нет
Всего: 1



А зачем здесь Reflection?

Если вы можете получить версию сервера, то пишете что то вроде:
Код

Server server = null;
if("123".equals(serverType)) {
    server = new Server123();
} else if ("456".equals(serverType)) {
    server = new Server456();
}


Или вам совсем-совсем неизвестны классы во время компиляции?
(Судя по Class.forName("Server"+"123") все же известны)

Если совсем неизвестны, тогда да, через Reflection.
Но тогда и (Server123) obj тоже не получится.
Тут только с полями и методами тоже через Reflection работать.




Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL ICQ   Вверх
koreyko
Дата 7.9.2015, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 20.4.2010

Репутация: нет
Всего: нет



Спасибо. Я хотел сделать "красивое" решение без if\else. 

Насчет известности классов во время компиляции, мне неизвестно какой будет конкретно из определенного перечня на этапе выполнения. Грубо говоря, какой именно из Server123, Server456, Server789 и т.д.
PM MAIL   Вверх
jManiak
Дата 7.9.2015, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 6.2.2007
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Ну это у вас значение не известно. Это номрально. Классы то вы все знаете на момент компиляции.
В этом случае reflection не нужен.

Reflection нужен тогда, когда вы именно КЛАССЫ не знаете на этапе компиляции.
Т.е. они готовятся отдельно/позже/другими людьми и подкладываются только при выполнении.

А то, что if\else, так это не страшно. Если только там у вас 200 таких if\else, и это повторяется 20 раз по всему коду. Тогда страшно было бы.

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL ICQ   Вверх
koreyko
Дата 7.9.2015, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 20.4.2010

Репутация: нет
Всего: нет



Понятно, спасибо!
PM MAIL   Вверх
LSD
Дата 7.9.2015, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Desclamer: сильное увлечение энтерпрайзностью порождает трудноподдерживаемых монстров.


Но если хочется совсем красиво и "энтерпрайзно", то я бы использовал ServiceLoader. И вместо Server получать ServerFactory которая отдает номер версии, или даже наоборот умеет определять совместим ли сервер с данной версией, что-то типа Driver.acceptsURL(String)
Вот это будет полный энтерпрайз. smile 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0724 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.