2

再会,

我已经尝试过很好的谷歌搜索,甚至一些阅读,但不完全确定如何进行。这是问题所在:

当我调用duplicate()java.nio.Buffer 的任何实现时,我用原始缓冲区设置的字节顺序buf.order(ByteOrder.LITTLE_ENDIAN)不会被保留。这是个问题。所以我开始创建一个静态方法,它允许我像这个例子一样执行以下操作:

public static ByteBuffer endianPreservingDuplicate(ByteBuffer b){
    ByteOrder holder = b.order();
    ByteBuffer ret = b.duplicate();
    ret.order(holder);
    return ret;
}

这可行,但是有没有任何实际的方法可以做到这一点(可能是泛型?)而不必为每种类型(ByteBuffer、FloatBuffer、IntBuffer 等)实现这个函数?

4

2 回答 2

2

duplicate据编译器所知,这些不同类的方法之间没有任何关系;它们不是由任何超类型(超类或接口)定义的。因此,它们唯一的共同点在于它们的方法签名(名称和参数),而访问它的唯一方法是通过反射。同样对于order. 这是可能的,但会非常混乱,并且会干扰您的 IDE 帮助您查看代码在做什么的能力;这可能不值得。

此外,还有一个更大的问题:您的方法取决于ByteBuffer#order(ByteOrder)设置字节顺序;但是FloatBufferIntBuffer甚至没有这样的方法。他们确实有一个order()不带参数并返回它们的字节顺序的,但他们没有一个order(ByteOrder)接受字节顺序并采用它的。(这是因为它们的字节顺序并不是它们自己的:如果它们是字节缓冲区的包装器,那么它们使用它的字节顺序,如果它们是数组的包装器,它们使用系统的字节顺序。)

所以好消息是。. . 您不需要为每种类型都实现此方法,因为您不能。:-P

于 2012-11-27T22:57:40.497 回答
2

您可以结合使用泛型和反射,但这很丑:

public static <T extends Buffer> T endianPreservingDuplicate(T b) throws Exception {
    Class<?> clazz = b.getClass();
    Method getOrder = getMethod(clazz, "order");
    ByteOrder orderTemp = (ByteOrder) getOrder.invoke(b);
    Method duplicate = getMethod(clazz, "duplicate");
    @SuppressWarnings("unchecked") // cast is safe
    T copy = (T) duplicate.invoke(b);
    Method setOrder = getMethod(clazz, "order", ByteOrder.class);
    setOrder.invoke(copy, orderTemp);
    return copy;
}

private static Method getMethod(Class<?> clazz, String name, Class<?>...params) throws NoSuchMethodException {
    try {
        Method method = clazz.getDeclaredMethod(name, params);
        method.setAccessible(true);
        return method;
    } catch (NoSuchMethodException e) {
        Class<?> superclass = clazz.getSuperclass();
        if (!superclass.equals(Buffer.class)) {
            return getMethod(superclass, name, params);
        } else {
            throw new NoSuchMethodException("no " + name + " method");
        }
    }
}

order()如果没有或作为参数duplicate()传递的 Buffer 实现,它将抛出异常。b

最好的选择是为每种缓冲区类型创建单独的方法。

部分归功于ruakh审查​​代码并提出更新建议。

于 2012-11-27T23:03:27.637 回答