2011-07-24 2 views
2

Я хочу реализовать своего рода шаблон переноса объекта. Итак, у меня есть метод, который заполняет свойства объекта через BeanUtils.copyProperties (.., ..) (общий Apache).java generic cast question

Вот код:

public abstract class BaseTO<TObject> { 

    public Long id; 

    /*** 
    * Obtains id of the object that´s transfered 
    * @return object´s id 
    */ 
    public Long getId() { 
     return id; 
    } 

    /**** 
    * set transfered object´s id 
    * @param id object´s id 
    */ 
    public void setId(Long id) { 
     this.id = id; 
    } 

    /*** 
    * Fill transfer object properties. 
    * @param entity entity to be transfered 
    * @return self reference 
    */ 
    public BaseTO<TObject> build(TObject entity){ 
     try { 
      BeanUtils.copyProperties(this, entity); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     customDataTransformation(entity); 
     return this; 
    } 

    protected void customDataTransformation(TObject entity) { 
    } 


} 

CustomerTO Класс

public class CustomerTO extends BaseTO<Customer> { 

    private String name; 
    private String surname; 
    private String email; 
    private String sex; 
    private DocumentType documentType; 
    private String documentNumber; 

    --- getters and setters 

    @Override 
    protected void customDataTransformation(Customer entity) { 
     this.sex = Sex.MALE.equals(entity.getSex()) ? "M" : "F"; 
    } 


} 

проблема

CustomerTO toEdit = (CustomerTO) (customerId!=null ? new CustomerTO().build(entityObject):new CustomerTO()); 

, как вы можете видеть, здесь есть приведение к (CustomerTO). Я хочу, чтобы избежать этого, чтобы сделать код более простым.

Возможно ли, что public BaseTO build (объект TObject) может вернуть объект подкласса ??

Надеюсь быть ясным.

Заранее спасибо.

+0

Вы пишете все это только потому, что хотите пропустить 1 небольшой актерский состав? – toto2

+0

@toto: Я думаю, что вопрос - это больше, чем просто кастинг, но также и проверка времени компиляции. +1 к вопросу. –

+0

@toto. Нет, я буду использовать во многих местах. –

ответ

1

Может попробовать это:

class BaseTO<TObject, R extends BaseTO<TObject,R>> { 

    public R build(TObject entity) { 

, а затем CustomerTO:

class CustomerTO extends BaseTO<Customer, CustomerTO> { 

или менее ограничительно, только изменить build подпись:

public <X extends BaseTO<TObject>> X build(TObject entity) { 

Но ИМХО лучше подход будет просто добавление конструктора в TO с параметром TObject.

public BaseTO(TObject entity) { 
     try { 
      BeanUtils.copyProperties(this, entity); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     customDataTransformation(entity); 
} 

затем в каждом классе-создать простой конструктор

 public CustomerTO(Customer entity) { 
     super(entity); 
    } 

и забыть о методе build и использовать его просто

CustomerTO toEdit = (customerId!=null ? new CustomerTO(entityObject):new CustomerTO()); 
+0

. Я буду использовать ваши последние ок. –

1

компилируется:

public class BaseTO<T> { 

    public BaseTO<T> build(T entity) { 
     return this; 
    } 

    public static class CustomerTO extends BaseTO<String> { 

     @Override public CustomerTO build(String string) { 
      return (CustomerTO) super.build(string); 
     } 
} 

но вы должен будет переопределить build для всех подклассов BaseTO. Вы пишете явно листинг только один раз, а не каждый раз, когда вы вызываете build.

EDIT: см. Пункт, поднятый @Paul в комментариях выше. Возможно, вы страдаете от «дайте человеку молоток, и все выглядит как гвоздь для него».