我想知道Java中是否有可能不仅检查instanceof
,还检查给定方法是否可用于泛型类型变量。
new LruCache<K, V>(size) {
@Override
protected int sizeOf(final K key, final V value) {
// if (value hasmethod getByteCount)
return super.sizeOf(key, value);
}
};
它存在吗?
答案 0 :(得分:2)
更好的解决方案是将V
限制为具有该方法的接口。但如果你不能这样做:
boolean hasMethod = false;
try {
Method m = value.getClass().getDeclaredMethod("byteCount", null);
hasMethod = true;
}
catch (NoSuchMethodException e) {
}
catch (SecurityException e) {
// you don't have access to the method from your package
}
假设您没有关于该方法的参数。否则,将参数类型作为参数传递给getDeclaredMethod
。
如果该方法是公开的,请改用getMethod
。
编辑评论是正确的,指出这不会从超类型获取方法。如果你需要,你可以使用它(它跳过Object
方法,因为所有对象都有这些,所以对其中一个方法的测试是没有价值的):
<V> boolean hasInheritedDeclaredMethod(V value, String methodName)
{
Class c = value.getClass();
boolean hasMethod = false;
while (!hasMethod && c != Object.class) {
try {
Method m = c.getDeclaredMethod(methodName, null);
hasMethod = true;
}
catch (NoSuchMethodException e) { }
// you don't have access to the method from your package
catch (SecurityException e) { break; }
if (!hasMethod && c != Object.class)
c = c.getSuperclass();
}
return hasMethod;
}
答案 1 :(得分:1)
我认为你问的问题与你试图解决的问题并不完全相同。使用java泛型,您可以通过以下方式安全地执行此类型:
您只需创建一个具有getByteCount()
:
interface IByteCountable { // some descriptive name
int getByteCount();
}
然后从LruCache
创建一个派生类,它强制执行类型正确性:
class MyLruCache<K, V extends IByteCountable> extends LruCache<K, V> {
@Override protected int sizeOf(final K key, final V value) {
// compiler can check this, no reflection
int byteCountOfValue = value.getByteCount();
return 0;
}
}
然后,您只能创建MyLruCache
的实例,其中某些类型为V
,实现IByteCountable
答案 2 :(得分:0)
您可以使用org.springframework.util.ReflectionUtils
public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes)
从类或超类中获取方法。