Java Android中的toString()实现存在问题

Java Android中的toString()实现存在问题,java,android,Java,Android,我有一个稍微高级一点的类,我正试图为它编写一个toString() 为了完成我试图做的事情,我需要能够在执行toString()时更改某些变量的赋值 为了简单起见,我将删除一堆东西,除了允许它工作的东西 public enum PacketElementType { NONE((byte)0, "None"), BYTE((byte)1, "Byte"), SHORT((byte)2, "Short"), INT((byte)3, "Int"), LONG

我有一个稍微高级一点的类,我正试图为它编写一个
toString()

为了完成我试图做的事情,我需要能够在执行
toString()
时更改某些变量的赋值

为了简单起见,我将删除一堆东西,除了允许它工作的东西

public enum PacketElementType {
    NONE((byte)0, "None"),
    BYTE((byte)1, "Byte"),
    SHORT((byte)2, "Short"),
    INT((byte)3, "Int"),
    LONG((byte)4, "Long"),
    FLOAT((byte)5, "Float"),
    STRING((byte)6, "String"),
    BIN((byte)7, "Bin");

    private final byte typeValue;
    private final String typeName;

    PacketElementType(byte type, String name)
    {
        this.typeValue = type;
        this.typeName = name;
    }

    public String getTypeName() {
        return typeName;
    }

    public byte getTypeValue() {
        return typeValue;
    }
}

public class Packet {
    private final int DEFAULT_SIZE = 1024 * 2;
    private final int ADD_SIZE = 1024;

    private byte[] _buffer = new byte[1];
    private int _ptr = 0;
    private int _bodyStart = 0;
    private int _elements, _bodyLen = 0;

    private int op;
    private long id;

    public Packet(int op, long id) {
        setOp(op);
        setId(id);

        _buffer = new byte[DEFAULT_SIZE];
    }

    public int getOp() {
        return op;
    }

    public void setOp(int op) {
        this.op = op;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public PacketElementType peek() {
        int pie = _ptr;
        if (pie + 2 > _buffer.length)
            return PacketElementType.NONE;
        return PacketElementType.values()[_buffer[_ptr]];
    }

    protected Packet putSimple(PacketElementType type, byte... val) {
        int len = val.length + 1;
        this.ensureSize(len);

        _buffer[++_ptr] = type.getTypeValue();
        System.arraycopy(val, 0, _buffer, _ptr, val.length);
        _ptr += val.length;

        _elements++;
        _bodyLen += len;

        return this;
    }

    public Packet putByte(byte val) {
        return this.putSimple(PacketElementType.BYTE, val);
    }

    public Packet putByte(boolean val) {
        return this.putByte(val ? (byte) 1 : (byte) 0);
    }

    public byte getByte() throws Exception {
        if (this.peek() != PacketElementType.BYTE)
            throw new Exception("Expected Byte, got " + this.peek().getTypeName() + ".");

        _ptr += 1;
        return _buffer[++_ptr];
    }

    protected void ensureSize(int required) {
        if (_ptr + required >= _buffer.length) {
            byte[] b = new byte[_buffer.length + Math.max(ADD_SIZE, required * 2)];
            System.arraycopy(_buffer, 0, b, 0, _buffer.length);
            _buffer = b;
        }
    }

    private boolean isValidType(PacketElementType type)
    {
        return (type.getTypeValue() >= PacketElementType.BYTE.getTypeValue() && type.getTypeValue() <= PacketElementType.BIN.getTypeValue());
    }

    protected String toStringHack()
    {
        StringBuilder result = new StringBuilder();
        int prevPtu = _ptr;
        _ptr = _bodyStart;

        try {
            result.append(String.format("Op: %1$08d %3$s, Id: %2$016d\r\n", this.getOp(), this.getId(), Op.getName(this.getOp())));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return result.append("Failed to convert packet to string").toString();
        }

        PacketElementType type;
        for (int i = 1; (this.isValidType(type = this.peek()) && _ptr < _buffer.length); ++i)
        {
            if (type == PacketElementType.BYTE)
            {
                byte data = 0;
                try {
                    data = getByte();
                } catch (Exception e) {
                    e.printStackTrace();
                    result.append("Failed to parse element at position ").append(i);
                    continue;
                }
                result.append(String.format("%1&03d [%2$s] Byte   : %3$s", i, String.format("%1$016d", data), data));
            }
        }

        return result.toString();
    }

    //TODO: toString
    @Override
    public String toString()
    {
        return toStringHack();
    }
}


public class Op {

    public class Msgr
    {

    }

    public static String getName(int op) throws IllegalAccessException {
        for (Field field : Op.class.getFields())
        {
            if ((int)field.get(null) == op)
                return field.getName();
        }

        for (Field field : Op.Msgr.class.getFields())
        {
            if ((int)field.get(null) == op)
                return field.getName();
        }

        return "?";
    }
}
对我来说,我首先将其放入内置测试类中,然后在主活动的onCreate中尝试它

toString()
将只返回Op和Id,因为
\u ptr
位于,
peek()
将尝试从该位置开始读取字节,而不是从0开始读取1字节

编辑
好像<代码>\u ptr=\u bodyStart被视为不是赋值,这可能吗?

您看到的结果是正常的-调试器在求值之前向您显示这些变量。在这一行后面添加一行(如日志或smth)并在其上设置断点。

因此,我只缺少一个小细节。。。。。一点也不小,我很抱歉没有早点看到
toString()
将失败,原因是
String.format()
调用格式错误,以及在
toString()
完成后未能将
ptr
设置回其原始值

result.append(String.format("%1&03d [%2$s] Byte   : %3$s", i, String.format("%1$016d", data), data));
应该是(就在
%1
之后,我有一个
&
而不是
$

在返回字符串之前,我需要执行以下操作

ptr = prevPtu;
在这种情况下,会发生以下情况:


将其作为独立类进行调试的步骤是什么?您将拥有一个main方法,该方法创建一个Packet对象,然后在最终调用toString()之前设置一些数据?你能发布测试代码吗?谢谢你的关注!~我继续编辑了我的问题,提供了更多细节和遗漏的课程^^嘿,听你这么说,我现在不知道我在哪里会遇到这个问题,感觉ti可能与线程相关。看见
String hello = String.format("%1$03d [%2$s] Byte   : %3$d\r\n", i, StringUtils.leftPad(String.format("%02X", data), 16, '.'), (int) data);
ptr = prevPtu;