简体   繁体   中英

Why doesn't @TupleConstructor generate constructor

class Test {
    @TupleConstructor(includeFields=true)
    static class TestObject {
        private int a = 1;
        protected int b = 2;
        public int c = 3;
        int d = 4;
        String s = "s";
    }

    static main(args) {
        print new TestObject(1, 2, 3, 4, '3')
    }

}

Gives me:

Caught: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: in.ksharma.Test$TestObject(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.String)
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: in.ksharma.Test$TestObject(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.String)
    at in.ksharma.Test.main(Test.groovy:17)

Why didn't it generate the constructor?

If you do:

TestObject.constructors.each {println it}

You will see that @TupleConstructor has generated following constructors:

public in.ksharma.Test$TestObject(in.ksharma.Test,int,java.lang.String,int,int,int)
public in.ksharma.Test$TestObject(in.ksharma.Test,int,java.lang.String,int,int)
public in.ksharma.Test$TestObject(in.ksharma.Test,int,java.lang.String,int)
public in.ksharma.Test$TestObject(in.ksharma.Test,int,java.lang.String)
public in.ksharma.Test$TestObject(in.ksharma.Test,int)
public in.ksharma.Test$TestObject(in.ksharma.Test)

There are two issues here.

  1. The generated constructor has wrong order of fields and hence the constructor call doesn't match. This limitation arises because reflection API does not guarantee that it'll return the fields of a Java class in order they were defined. The javadoc for Class.getFields() says this:

Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object. The elements in the array returned are not sorted and are not in any particular order .

  1. The inner class is not static. So the first argument in the constructor is expected to be an instance of enclosing class.

To fix it make the nested class static and use named parameter notation:

print new TestObject(a:3, b:3, c:4, d:5, s:'3')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM