Java调用同级类上的方法

Java调用同级类上的方法,java,Java,你好 我试过谷歌搜索,甚至读过一些书,但不确定如何继续。问题是: 当我在java.nio.Buffer的任何实现上调用duplicate()时,我用原始缓冲区buf.order(ByteOrder.LITTLE_ENDIAN)设置的字节顺序不会被保留。这是一个问题。因此,我开始创建一个静态方法,该方法将允许我执行以下类似于此示例的操作: public static ByteBuffer endianPreservingDuplicate(ByteBuffer b){ ByteOrder

你好

我试过谷歌搜索,甚至读过一些书,但不确定如何继续。问题是:

当我在java.nio.Buffer的任何实现上调用
duplicate()
时,我用原始缓冲区
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等)实现此函数?

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

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


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

就编译器所知,这些不同类上的

duplicate
方法之间没有关系;它们不由任何超类型(超类或接口)定义。因此,它们唯一的共同点在于它们的方法签名(名称和参数),而唯一的访问方式是通过反射。对于
订单
也是如此。这是可能的,但会非常混乱,并且会干扰IDE帮助您查看代码的功能;这可能不值得

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


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

您可以使用泛型和反射的组合,但这很难看:

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");
        }
    }
}
publicstatict endianPreservingDuplicate(tb)抛出异常{
Class clazz=b.getClass();
方法getOrder=getMethod(clazz,“order”);
字节顺序orderTemp=(字节顺序)getOrder.invoke(b);
方法复制=获取方法(clazz,“复制”);
@SuppressWarnings(“未选中”)//强制转换是安全的
T copy=(T)replicate.invoke(b);
方法setOrder=getMethod(clazz,“order”,ByteOrder.class);
调用(复制,orderTemp);
返回副本;
}
私有静态方法getMethod(类clazz、字符串名称、类…参数)抛出NoSuchMethodException{
试一试{
Method=clazz.getDeclaredMethod(名称、参数);
方法setAccessible(true);
返回法;
}捕获(无此方法例外){
Class superclass=clazz.getSuperclass();
如果(!superclass.equals(Buffer.class)){
返回getMethod(超类、名称、参数);
}否则{
抛出新的NoSuchMethodException(“no”+name+“method”);
}
}
}
如果将不带
order()
duplicate()
的缓冲区实现作为
b
参数传递,则会引发异常

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


部分归功于对代码的审阅和更新建议。

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

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");
        }
    }
}
publicstatict endianPreservingDuplicate(tb)抛出异常{
Class clazz=b.getClass();
方法getOrder=getMethod(clazz,“order”);
字节顺序orderTemp=(字节顺序)getOrder.invoke(b);
方法复制=获取方法(clazz,“复制”);
@SuppressWarnings(“未选中”)//强制转换是安全的
T copy=(T)replicate.invoke(b);
方法setOrder=getMethod(clazz,“order”,ByteOrder.class);
调用(复制,orderTemp);
返回副本;
}
私有静态方法getMethod(类clazz、字符串名称、类…参数)抛出NoSuchMethodException{
试一试{
Method=clazz.getDeclaredMethod(名称、参数);
方法setAccessible(true);
返回法;
}捕获(无此方法例外){
Class superclass=clazz.getSuperclass();
如果(!superclass.equals(Buffer.class)){
返回getMethod(超类、名称、参数);
}否则{
抛出新的NoSuchMethodException(“no”+name+“method”);
}
}
}
如果将不带
order()
duplicate()
的缓冲区实现作为
b
参数传递,则会引发异常

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

部分学分用于审查代码并提出建议