java generic cast question
I want to implement a sort of transfer object pattern. So, i have a method that fills object´s properties via BeanUtils.copyProperties(..,..) (apache common).
Here is the code:
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 Class
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";
}
}
the problem
CustomerTO toEdit = (CustomerTO) (customerId!=null ? new CustomerTO().build(entityObject):new CustomerTO());
as you can see here have to cast to (CustomerTO). I want if it´s possible avoid that, to make the code simpler.
Is it posible that public BaseTO build(TObject entity) can return the object of the subc开发者_如何学Golass??
I hope to be clear.
Thanks in advance.
Maybe try this:
class BaseTO<TObject, R extends BaseTO<TObject,R>> {
public R build(TObject entity) {
and then CustomerTO:
class CustomerTO extends BaseTO<Customer, CustomerTO> {
or less restrictively, only change the build
signature:
public <X extends BaseTO<TObject>> X build(TObject entity) {
But IMHO better approach will be simply adding constructor to TO with TObject parameter.
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);
}
then in each extending class create simple constructor
public CustomerTO(Customer entity) {
super(entity);
}
and forget about the build
method and use it simply
CustomerTO toEdit = (customerId!=null ? new CustomerTO(entityObject):new CustomerTO());
This compiles:
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);
}
}
but you will have to override build
for all subclasses of BaseTO
. You write explicitly the cast only once instead of every time you call build
.
EDIT: see the point raised by @Paul in the comments above. You might be suffering from "give a man a hammer and everything looks like a nail to him."
精彩评论