On p414 of HFS the last-but-one bullet says that if you specify a type in <jsp:useBean> you can't set properties that exist only on the actual class type.
Yet I have tried this and I can set set the empID property of an Employee (extends person) that I passed into the form from a servlet (declared with Person reference), even though I specified type="foo.Person" (which doesn't have the empID property) in the <jsp:useBean> tag.
So it seems that, contrary to what is stated in HFS, you can actually get and set properties for a class even if the you declared a supertype and that supertype doesn't have those properties.
In the tests above I also specified class=... and the class name. Removing the "class=..." attribute makes the behaviour as stated in the book, so maybe I was a little harsh above.
I think the bullet point should read: If you specify a "type" attribute in <jsp:useBean> and do not specify the "class" attribute, you can set properties in <jsp:setProperty> ONLY on properties of the "type", but NOT on properties that exist only in the actual "class" type.
Howdy Roger, We're actually not 100% certain that the behavior you saw (where it DOES work if you say Type *and* Class) is guaranteed by the spec. It might be, but I haven't verified that.
So you're correct about how it works in Tomcat, though; it's a limitation *only* if you specify type but NOT class.
Although it might seem counter-intuitive that it works EVER (i.e. when you specify both type and class), when you think about it. Because in *normal* Java, this would of course never work:
Animal d = new Dog(); d.bark(); // Animal class does not have bark(), so this won't compile!
And technically, that's what you're doing when you specify a Type attribute in useBean... you're defining a type that may be a supertype for the actual object class type, and that supertype might NOT have the setter methods for the object class properties!
But using Type (for the declared type) *and* class, it still manages to work around this (at least in Tomcat), I believe because of the way the implementation uses reflection, and enables you to call methods that exist only in the class, even though the *declared type* doesn't have those methods! (And by methods, we're talking about the property setter methods).
So it does seem kind of weird that the tag takes care of this for you as long as you specify both type and class, even though in the Java polymorphic/type-safety sense, this shouldn't work. But the implementation takes care of it... although I am still checking as to whether this is in any way guaranteed in the spec (I don't think it is, but I'm checking).
In any case, this is NOT on the exam, just something for you to keep in mind. In real-life, unless we find otherwise, I would not trust this to work in all situations. In other words, assume that what you tried does work in Tomcat, but unless/until we find it in the spec, it might *not* work in all implementations. To be safe, I'd assume that using both type and class behaves like normal Java polymorphism, and that you can't set properties (which means invoking setter methods) that exist only in the class. But if you do not specify "type", then of course you are always safe.
I'm going to research this a little more, though, and since I don't remember seeing anything explicit, I have written the JSP spec lead to see what he says. If it's right there in plain words in the spec, and I just don't see it, he'll forgive me
Cheers, Kathy [ October 01, 2004: Message edited by: Kathy Sierra ]