Groovy字节数组被隐式转换为ArrayList

时间:2018-08-01 04:09:46

标签: java arrays arraylist groovy casting

我的错误:

  

groovy.lang.MissingMethodException:方法的无签名:静态test.getLittleEndianSize()适用于参数类型:(ArrayList)值:[[-128,0,0,0]]

我严格使用字节数组,从不在任何地方使用def / List,所以这真的让我失望。任何想法为什么会发生这种情况?据我所知,groovy并没有将byte []之类的原语重新定义为实现List,而且我还没有找到类似的错误。

这原本是让我在一个更大的项目中陷入困境,我将其简化为以下代码。

class test {
    static class Packet {
        byte[] data

        Packet(String data) {
            this.data = data.replaceAll(":", "").decodeHex()
        }

        int size() {
            return data.size()
        }
    }

    static class PacketList {
        List<Packet> packets
        long totalDataSize

        PacketList(String data) {
            packets = new ArrayList<Packet>()
            totalDataSize = 0
            addPacket(data)
        }

        void addPacket(String data) {
            packets += new Packet(data)
            totalDataSize += data.size()
        }

        long getLittleEndianSize() {
            if (packets.size() <= 0)
                return 0

            // Verifying that we're for sure using byte[]
            byte[] firstPacketBytes = packets[0].data
            if (firstPacketBytes?.size() > 0) {

                byte[] lilSizeBytes = Arrays.copyOfRange(firstPacketBytes, 0, 4)
                return getLittleEndianSize(lilSizeBytes)
            }
            return 0
        }

        // No logic in place to decrement size yet
        // No real need for this test
        //
        long getTotalDataSize() {
            return totalDataSize
        }
    }


    static long getLittleEndianSize(byte[] data) {
        if (data?.size() < 4) return -1

        long returnVal = 0
        for (int i = 0; i < 4; i++) {
            returnVal += ((long) data[i] & 0xffL) << (8 * i)
        }

        return returnVal
    }


    static void main(String[] args) {
        String testByteStr = "80:00:00:00:ff:d8:11:12:13:14:15:d9:ff"

        def packets = new PacketList(testByteStr)
        println "${packets.getTotalDataSize()} bytes | Little Endian Header: ${packets.getLittleEndianSize()}"
    }
}

1 个答案:

答案 0 :(得分:1)

groovy 2.4.11

有问题的简化班:

public class A{
    public static long fa(byte[]b){
        return b.length;
    }
    static class B{
        byte[] b="123".getBytes();
        long fb(){
            return fa(b); // <<< line 9
        }
    }

    public static void main(String [] arg){
        System.out.println ( ">>>" + new B().fb() );
    }
}

引发异常:

groovy.lang.MissingMethodException: No signature of method: static A.fa() is applicable 
for argument types: (java.util.ArrayList) values: [[49, 50, 51]]
Possible solutions: fa([B), is(java.lang.Object), wait(), any(), find(), wait(long)
   at A$B.fb(ConsoleScript49:9)
   at A.main(ConsoleScript49:14)

似乎groovy无法从外部类中找到静态方法...

您看到(java.util.ArrayList)错误,因为groovy尝试查找该方法的不同变体,并且可能是最后一次尝试。

在Java中,此代码已成功编译。

要在groovy中解决此问题,请在外部类或内部类上添加@groovy.transform.CompileStatic批注,或指定确切的方法位置:

        return A.fa(b); // <<< line 9