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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рефлексия и интерфейсы 
:(
    Опции темы
HugeX
Дата 18.6.2010, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрый день всем.
Я при помощи рефлексии загружаю класс, который наследует интерфейс и создаю объект. Подскажите, пожалуйста, как преобразовать объект этого класса в объект интерфейса.
PM MAIL   Вверх
AntonSaburov
Дата 18.6.2010, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

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



Странная фраза - если класс реализует интерфейс, то объект этого класса реализует интерфейс. И к нему можно обращаться как к интерфейсом. Не понятна проблема.
PM MAIL WWW ICQ   Вверх
powerOn
Дата 18.6.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


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

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



Тоже не особо понял что имеется ввиду. Может downcasting нужен?

Код

SomeInterface instance= (SomeInterface) Class.forName("somepackage.SomeClass").newInstance();



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
priam220
Дата 11.11.2010, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



не совсем понимаю зачем рефлексия нужна в Java. Прочитал статью на оракловом портале. Куча примеров, заканчивается и начинается тем, что это вот такая фича, которой нет не в С не в Паскале, но так и не понял, что этот подход дает. Видел в проектах применение рефлексии, но везде можно было бы обойтись и без нее. Кое где попадается фразы, что это ускоряет процесс обработки кода. Местами - обратное. 
Хотелось бы узнать, что дает рефлексия в Java , без чего нельзя жить. Рефлексивный код, скажем сравнения классов, выглядит как то чуждо на фоне остального объектного кода, но все же его пишут.
PM MAIL   Вверх
Skipy
Дата 11.11.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Цитата(priam220 @ 11.11.2010,  11:21)
Хотелось бы узнать, что дает рефлексия в Java , без чего нельзя жить.

Если бы без нее нельзя было жить - использовали бы повсеместно.

Рефлексия нужна там, где она нужна. И местами она оказывается не просто полезной, а до безобразия полезной. 

Например, есть у Вас интерфейс, методы которого надо вызывать в GUI-потоке. Стандартный вариант - вокруг метода написать обертку с SwingUtilities.invokeLater. Громоздко, за обертками кода не видно. Вариант рефлексии - создать динамический прокси, который будет перехватывать вызовы и везде, где надо, добавлять обертку. Тогда в реализации интерфейса можно обойтись просто аннотациями - @CallInGUIThread. Код чистый и понятный.

Это первое, что на ум пришло. А если начну думать - до ночи писать буду. У нас в текущем проекте на рефлексии очень много чего построено.

Это сообщение отредактировал(а) Skipy - 11.11.2010, 12:05


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
priam220
Дата 12.11.2010, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Skipy,  спасибо что ответил, но прошу понять меня правильно, - далеко не все крутые джависты работали со свингом, а не крутые и в смятку, - подавно. Хотелось бы простой пример, на котором бы стало понятно, что вот мол да, без рефлексии - никуда. Или чем лучше newInctance от простого new(). Вот например сетается форма из бина, свинговая, кстати:
 
        this.setTitle(visualBean.getClass().getAnnotation(VisualBean.class).value());
Неужели все только для того, что бы сеттеры убрать? А чем хуже так:
       this.setTitle(vb.getTitle);
Думаю все согласятся, что вторая строчка куда понятнее, нагляднее и проще. А когда таких строк с 3-4 десятка?  smile  

    




Это сообщение отредактировал(а) priam220 - 12.11.2010, 01:04
PM MAIL   Вверх
mantracoder
Дата 12.11.2010, 02:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(priam220 @ 12.11.2010,  01:02)
Хотелось бы простой пример, на котором бы стало понятно, что вот мол да, без рефлексии - никуда. Или чем лучше newInctance от простого new().

Возьмем другой пример - Hibernate, облегчающий жизнь при работе с БД. 

Задача Hibernate - сохранять / извлекать пользовательские объекты из реляционной базы данных. Программисту необходимо сделать мэппинг (будь то аннотации или XML-документ(ы)), описывающий соответствие полей объекта полям таблицы, взаимосвязи объектов и т.д.

Для программиста существуют бизнес-объекты типа Customer, Order, Invoice. Hibernate абстрагирован от пользовательской логики - для него любой мой бизнес-объект - просто Object, а мэппинг - инструкция, какие именно свойства этого объекта каким полям таблицы соответствуют.

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

В большинстве случаев рефлексию целесообразно использовать там, где необходимо максимально абстрагироваться от самой точки приложения этого полезного инструмента. 
PM MAIL   Вверх
Skipy
Дата 12.11.2010, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Цитата
Хотелось бы простой пример, на котором бы стало понятно, что вот мол да, без рефлексии - никуда.


Я еще раз говорю - "никуда" бывает крайне редко. Чаще бывает "можно, но намного сложнее". Например.

У Вас объект вызывает некий интерфейс, через который получает данные. Это интерфейс, вернее, его реализация, смотрит на пул сервисов. Берет оттуда произвольный и вызывает. А сервисы имеют тенденцию периодически отваливаться. Соответственно, надо обеспечить устойчивость вызова.

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

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

Еще пример - обработчик исключений верхнего уровня. Те, которые долетели до самого верха, надо обработать. Пишете методы типа handleCOMM_FAILURE, handleTRANSIENT, handleExSystem - для тех исключений, которые хотите обработать. Дальше, в catch берете имя класса пойманного исключения, приписываете handle и ищете в обработчике метод с таким именем. Нашли - вызываете.

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

Еще пример - ниже.

Цитата
Или чем лучше newInctance от простого new(). 


У Вас класс, параметризованный. 

Код
public class MyClass<T>{

    public T createObjInstance(){
        ... ?
    }

}


Вам нужно создавать экземпляр по типу параметризации. new T() Вам сделать никто не даст - в runtime типа у Вас нет. А вот если Вы туда передадите при содании Class<T>, то сделать clazz.newInstance() получится:

Код
public class MyClass<T>{

    private Class<T> clazz;

    public MyClass(Class<T> clazz){
        this.clazz = clazz;
    }

    public T createObjInstance(){
        return clazz.newInstance();
    }

}


И НИКАК иначе Вы экземпляр по типу параметризации не создадите. Вот тут уже действительно без рефлексии никуда.

Цитата

например сетается форма из бина, свинговая, кстати:

this.setTitle(visualBean.getClass().getAnnotation(VisualBean.class).value());

Неужели все только для того, что бы сеттеры убрать? А чем хуже так:

this.setTitle(vb.getTitle);


Это не самый хороший пример, но тем не менее. Чем это лучше? Могу предположить, тем, что у бина во втором случае обязательно должен быть метод getTitle. Если он нужен только для отображения заголовка формы - такого метода быть не должно, он не относится к бизнес-логике бина. Это некая вспомогательная информация. Аннотации для этого вполне подходят.


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
priam220
Дата 12.11.2010, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Java Рефлексия,  - это возможность процедурного подхода в разработке на полностью объектном языке. Пришел к такому выводу. Я прав?
PM MAIL   Вверх
priam220
Дата 13.11.2010, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Skipy,  спасибо тебе за такой развернутый ответ и за активность. Но все равно осталось много не понятного. 
1. Хорошо понял только второй пример, с обработчиком ислкючений. Еще не совсем понял, зачем люди пишут instanceof в блоке catch(Throwable e){}, ведь в каждой книже по java написано, что исключения надо обрабатывать в поряке обратном наследования:
т.е. 
catch(MyRuntimeException e){}
catch(RuntimeException e){}
Но в целом понятно. Наверное в верхнем уровне прилажения это действительно целесообразно, т.к. исключений может быть много.

2. Третий пример не понятен. <T> - эта шаблоны С++. Означает, что этот класс может обрабатывать переменный тип данных одной и той же логикой. В связи с чем мне не понятно, что означает new T(), и главное зачем нам нужен экземпляр параметризованного класса, параметр в который мы не передали.




Это сообщение отредактировал(а) priam220 - 13.11.2010, 00:54
PM MAIL   Вверх
Skipy
Дата 13.11.2010, 11:57 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Цитата(priam220 @ 13.11.2010,  00:48)
Skipy 2. Третий пример не понятен. <T> - эта шаблоны С++. Означает, что этот класс может обрабатывать переменный тип данных одной и той же логикой. В связи с чем мне не понятно, что означает new T(), и главное зачем нам нужен экземпляр параметризованного класса, параметр в который мы не передали.

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

P.S. Не совсем понимаю Ваши намерения. Вы хотите убедиться, что reflection - ненужный механизм? Или что? Я ЕЩЕ раз говорю - практически всё, что можно сделать через reflection, можно и без него. Но с ним - намного удобнее. Если не видите смысла, не используйте. Никто не заставляет. Когда реально понадобится - будете использовать.

Это сообщение отредактировал(а) Skipy - 13.11.2010, 11:59


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
priam220
Дата 13.11.2010, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Звезды горят, значит это кому-нибудь нужно. Это понятно. Меня больше интересовал вопрос зачем оно кому-нибудь нужно. Но ситуация проясняется, спасибо.  Недостаток конечно, но если бы его не было, никто ничего никогда не спрашивал бы. Вообще был бы благодарен, если бы объяснили последний пример с рефлексией, или ссылку почитать. Потому что не могу понять этот код:
Код

public class MyClass<T>{

    private Class<T> clazz;

    public MyClass(Class<T> clazz){
        this.clazz = clazz;
    }

    public T createObjInstance(){
        return clazz.newInstance();
    }

}

MyClass <Integer> mc = new MyClass<Integer>(2); - понятно
MyClass <String> mc = new MyClass<String>("2"); - понятно
MyClass  mc = new MyClass(Integer.class); - нет


Это сообщение отредактировал(а) priam220 - 13.11.2010, 16:16
PM MAIL   Вверх
Skipy
Дата 13.11.2010, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Цитата(priam220 @ 13.11.2010,  16:15)
не могу понять этот код:
Код

public class MyClass<T>{

    private Class<T> clazz;

    public MyClass(Class<T> clazz){
        this.clazz = clazz;
    }

    public T createObjInstance(){
        return clazz.newInstance();
    }

}

MyClass <Integer> mc = new MyClass<Integer>(2); - понятно
MyClass <String> mc = new MyClass<String>("2"); - понятно
MyClass  mc = new MyClass(Integer.class); - нет

Я Вам по секрету скажу - компилятору тоже не до конца понятно. И потому он предупреждение на последнем варианте выдаст. Правильно - так:

Код
MyClass<Integer>  mc = new MyClass<Integer>(Integer.class);


Мы параметризуем класс типом Integer и класс этого же типа передаем в конструктор. Соответствие типов контролируется, вот это вызовет ошибку:

Код
MyClass<Integer>  mc = new MyClass<Integer>(String.class);


Нам нужен экземпляр Class<Integer>, чтобы создать экземпляр Intener внутри, через newInstance. Никак иначе мы это сделать не можем, в runtime нет сведений о типе T. Зато есть класс - Integer.class. А соответствие типов контролируется компилятором.


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
priam220
Дата 14.11.2010, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Теперь понял. Хороший пример. Но почему "никак иначе", а если так:

Код

public class MyClass<T>{
    private T obj;

    public MyClass(T obj){
        this.obj = obj;
    }
   
    public Object createObjInstance(){
     if (obj instanceof Integer)
     {
             return new Integer(2);    
     }    
     throw new RuntimeException("Not acceptable type");
    }
    
    public static void main (String[] args){
     MyClass<Integer> mc = new MyClass<Integer>(new Integer('1'));
     Object obj = mc.createObjInstance();
     if (obj instanceof Integer){
         System.out.println(obj);
     }
    }
}

PM MAIL   Вверх
jk1
Дата 14.11.2010, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

а если так:

Вы ветками if (obj instanceof Integer) будете перебирать все доступные типы из пространства имен?
Если вы собираетесь параметризовать класс одним конкретным типом, то параметризация и не нужна - указывайте конкретный тип. Если предполагается 5-6 штук, то можно налепить 5-6 веток ветвления для разбора по типу, но это, как говорил Skipy, геморно и  некрасиво. А вот если предполагается параметризация абсолютно любым классом, тут if'ов не напасешься.

Это сообщение отредактировал(а) jk1 - 14.11.2010, 09:50


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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