Property<T>
. And write something like this:public class ClientCode {
Object model;
public ClientCode(Object model) {
this.model = model;
}
public void businessLogic() {
Property<String> name = new Property<String>("userName", model);
Property<Date> dob = new Property<Date>("dateOfBirth", model);
Property<Boolean> isGood = new Property<Boolean>("isGood", model);
if (isGood.value() && dob.value().before(new Date(1990, 10, 24))) {
System.out.println("One good adult user: " + name.value());
}
}
public static void main(String[] args) {
new ClientCode("ignore me").businessLogic();
}
}
Naive but natural. And now the implementation of
Property<T>
:package common;
public class Property<T> {
String name;
T value;
public Property(String name, Object container) {
this.name = name;
this.value = (T) "hello world";
// org.apache.common.weird.helper.util.BeanAccessUtil.
// getProperty(container, name);
}
public T value() { return value; }
}
Looks pretty convincing, right? But surprise! Do you think this code will throw a
ClassCastException
from within Property<T>
? Seems like it should; we even have a variable that, in case of it being type Date, cannot accept a string in assignment. Right? Wrong...
As you know, generic type information is lost in compilation. As a result, all the compiled class knows about
value
type is that it is something. It is actually an Object
, and can accept whatever is assigned. More, the method value()
also returns an Object
. But the client is sure, due to generic parameterization, that it returns the expected type. But it does not. And the exception is thrown right in the client code.
Thankfully it's not the case in C++ ^-^*
ReplyDelete