我能否知道给定的方法是否存在?

时间:2015-01-21 14:03:34

标签: java generics

我想知道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);
    }
};

它存在吗?

3 个答案:

答案 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)

从类或超类中获取方法。