Java调用同级类上的方法
你好 我试过谷歌搜索,甚至读过一些书,但不确定如何继续。问题是: 当我在java.nio.Buffer的任何实现上调用Java调用同级类上的方法,java,Java,你好 我试过谷歌搜索,甚至读过一些书,但不确定如何继续。问题是: 当我在java.nio.Buffer的任何实现上调用duplicate()时,我用原始缓冲区buf.order(ByteOrder.LITTLE_ENDIAN)设置的字节顺序不会被保留。这是一个问题。因此,我开始创建一个静态方法,该方法将允许我执行以下类似于此示例的操作: public static ByteBuffer endianPreservingDuplicate(ByteBuffer b){ ByteOrder
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
参数传递,则会引发异常
最好的选择是为每种缓冲区类型创建单独的方法
部分学分用于审查代码并提出建议