Does EL support overloaded methods?
Asked Answered
G

2

31

I upgraded my Java EE web application to use newer PrimeFaces version and suddenly the call of an overloaded bean method in an action attribute of PrimeFaces commandlink did not work anymore. I tried to use JSF default commandlink to test it and this one did not work either.

The method signatures are as follows:

public void updateA(B b);
public void updateA(A a);

It always tried to cast A to B.

More curious, how could it work before the upgrade?

Gascon answered 19/3, 2012 at 0:31 Comment(0)
C
42

EL does not support it, no. It'll always be the first method of the Class#getMethods() array whose name (and amount of arguments) matches the EL method call. Whether it returns the same method everytime or not depends on the JVM make/version used. Perhaps you made a Java SE upgrade in the meanwhile as well. The javadoc even says this:

The elements in the array returned are not sorted and are not in any particular order.

You should not rely on unspecified behaviour. Give them a different name.

Counterfeit answered 26/4, 2012 at 3:3 Comment(5)
Is there any (technical) reason why this is not supported in JSF 2 any more? I'm pretty sure that this was possible in JSF 1.x versions, wasn't it?Nympholepsy
This is not JSF specific.Counterfeit
I had an equal problem, but in my case not always the first one was used. It seems to be quite randomly chosen.Frame
@alexvii: as answered, the getMethods() doesn't necessarily return a fixed order.Counterfeit
The fact that the searching for the most accurate overloaded method does not work with EL, sucks.Alguire
H
4

The way you can get around this is to create a generic method and do the 'routing' inside that method. I know that this might not be ideal, but you end up with less configurations in functions and XHTML pages.

if (A.class.isInstance(obj)) {
    A o = (A) obj;
    return method(o, highRes);
} else if (B.class.isInstance(obj)) {
    B o = (B) obj;
    return method(o, highRes);
} else if (C.class.isInstance(obj)) {
    C o = (C) obj;
    return method(o, highRes);
} else {
    throw new FacesException("Unsupported Conversion: " + obj);
}
Hearne answered 19/9, 2013 at 16:49 Comment(1)
Not ideal at all, in fact, it's a terrible suggestion. Besides some very specific cases (such as the implementation of the equals() method), you should never use this type of comparisons. Quoting Scott Meyers, from Effective C++: 'Anytime you find yourself writing code of the form "if the object is of type T1, then do something, but if it's of type T2, then do something else," slap yourself'.Verulamium

© 2022 - 2024 — McMap. All rights reserved.