Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Duplicate
-
Affects Version/s: 1.6.3
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
Number of attachments :
Description
It does not seem possible to overload a setter with multiple methods.
Groovy seems to randomly decide to fail with cast exceptions
rather than actually calling the correct setter. Here is the code:
public class Person {
// id is added by grails
String name
String email
Date birthdate
int age = 0
PersonSex sex = PersonSex.unknown
boolean active = true
void setBirthdate(String date)
{ // try to convert from string def df = new SimpleDateFormat("yyyy/MM/dd") birthdate = df.parse(date); }void setBirthdate(Number date)
{ birthdate = new Date(date) }}
I have a few tests to verify that I can create a user with a Date, String, or Long
With the code above it is not possible to set the bithdate to a Date
anymore as I always get a cast exception.
If I change "Number" to "Long" or "long" then the String test passes
but the number test fails. If I leave it as shown above then the
String test fails with this exception:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot
cast object '1975/10/29' with class 'java.lang.String' to class
'java.lang.Number'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToNumber(DefaultTypeTransformation.java:132)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:261)
at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2392)
at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3307)
at groovy.lang.MetaClassImpl.setProperties(MetaClassImpl.java:1506)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1483)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1404)
at org.codehaus.groovy.runtime.InvokerHelper.invokeConstructorOf(InvokerHelper.java:775)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeNewN(ScriptBytecodeAdapter.java:220)
at PersonTest.testPersonStringDate(PersonTests.groovy:32)
It seems like groovy is only able to work with a single setter method but it should be able to handle overloaded methods and properly call the one which matches the type.
Issue Links
- duplicates
-
GROOVY-2500
Assignment calls the wrong setter, depending on order of declaration
-
Here is the test code:
void testPersonDateDate()
{ Calendar c = new GregorianCalendar() c.setTime( new Date(0) ) c.set(Calendar.YEAR, 1975) c.set(Calendar.MONTH, Calendar.OCTOBER) c.set(Calendar.DATE, 29) c.set(Calendar.HOUR, 0) c.set(Calendar.MINUTE, 0) Date d = c.getTime() Person p = new Person(name:"Aaron Zeckoski",email:"azeckoski@vt.edu",age:34,birthdate:d) assert p.birthdate assert d == p.birthdate }void testPersonStringDate()
{ Person p = new Person(name:"Aaron Zeckoski",email:"azeckoski@vt.edu",age:34,birthdate:"1975/10/29") assert p.birthdate != null Calendar c = new GregorianCalendar() c.setTime( new Date(0) ) c.set(Calendar.YEAR, 1975) c.set(Calendar.MONTH, Calendar.OCTOBER) c.set(Calendar.DATE, 29) c.set(Calendar.HOUR, 0) c.set(Calendar.MINUTE, 0) Date d = c.getTime() assert d == p.birthdate }void testPersonNumberDate()
{ Person p = new Person(name:"Aaron Zeckoski",email:"azeckoski@vt.edu",age:34,birthdate:123456789l) assert p.birthdate Date d = new Date(123456789) assert d == p.birthdate }