2015-06-14 2 views
4

Можно ли каким-либо образом переместить все значения полей из одного объекта в другой без с использованием отражения? Итак, что я хочу сделать что-то вроде этого:Перемещение всех полей от одного объекта в другой

public class BetterThing extends Thing implements IBetterObject { 
    public BetterThing(Thing t) { 
     super(); 
     t.evolve(this); 
    } 
} 

Таким образом, метод evolve будет эволюционировать одного класса к другому. Аргументом будет <? extends <? extends T>>, где T - это класс объекта, вы вызываете evolve.

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

+4

Ваш выбор: (a) отражение или (b) явное назначение членов. –

+1

... или переключение с наследования на композицию. – aioobe

+0

, если вы говорите, что Thing находится во внешнем API, я думаю, что в нем нет метода эволюции. – AdamSkywalker

ответ

5

Как @OliverCharlesworth указывает, это невозможно сделать напрямую. Вам придется либо прибегнуть к размышлению (хотя я бы не рекомендовал его!), Либо серию заданий по каждому полю.

Другой вариант, хотя, было бы перейти от наследования к составу:

public class BetterThing implements IBetterObject { 
    Thing delegate; 

    public BetterThing(Thing t) { 
     this.delegate = t; 
    } 

    // Thing methods (delegate methods) 
    String thingMethodOne() { 
     return delegate.thingMethodOne(); 
    } 

    // BetterThing methods 
} 

Это обычно называют decorator pattern.

См: Prefer composition over inheritance?

+0

Действительно ли это [Decorator] (https://en.wikipedia.org/?title=Decorator_pattern)? – jaco0646

+0

@ jaco0646: это выглядит так. 1+ –

+0

@ jaco0646, да, спасибо. Добавил это к ответу. – aioobe

0

Вы должны попытаться свести к минимуму влияние производительности, используя библиотеку, которая ускорила рефлексивные операции путем кеширования результатов. Посмотрите Apache common-beanutils или Dozzer.

0

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

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

Смежные вопросы