为什么不@TupleConstructor生成构造函数 [英] Why doesn't @TupleConstructor generate constructor

查看:380
本文介绍了为什么不@TupleConstructor生成构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


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


给我:

 抓住:groovy.lang.GroovyRuntimeException:找不到匹配的构造函数:in.ksharma.Test $ TestObject(java.lang.Integer,java.lang.Integer,java.lang.Integer, java.lang.Integer,java.lang.String)
groovy.lang.GroovyRuntimeException:找不到匹配的构造函数:in.ksharma.Test $ TestObject(java.lang.Integer,java.lang.Integer,java .lang.Integer,java.lang.Integer,java.lang.String)
in.ksharma.Test.main(Test.groovy:17)

为什么不生成构造函数?

解决方案

您可以:

  TestObject.constructors.each {println it} 
@TupleConstructor 产生了以下构造函数:

  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)

这里有两个问题。


  1. 生成的构造函数的字段顺序错误,因此构造函数调用不匹配。这种限制的出现是因为反射API不能保证它会按照定义的顺序返回Java类的字段。 Class.getFields()的javadoc说:
    $ b


    返回包含 Field 对象的数组,该对象反映类或接口的所有可访问公共字段,由表示
    。 Class
    对象。 返回的数组
    中的元素没有排序并且没有任何特定顺序





    1. 内部类不是静态的。因此,构造函数中的第一个参数应该是一个包含类的实例。

    修复它使嵌套类静态并使用命名参数表示法:

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


    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')
    

    这篇关于为什么不@TupleConstructor生成构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆