我能知道给定的方法是否存在吗?
Can I know if a given method exists?
我想知道是否可以在 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);
}
};
它存在吗?
更好的解决方案是将 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
.
如果方法是 public,请改用 getMethod
。
EDIT 评论指出这不会从超类型获取方法是正确的。如果你需要,你可以使用这个(它跳过 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;
}
您可以使用org.springframework.util.ReflectionUtils
public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes)
从 class 或 super class 获取方法。
我认为您要问的问题与您要解决的问题并不完全相同。使用 java 泛型,您可以通过以下方式安全地执行此类型:
您可以简单地创建一个界面,该界面具有 getByteCount()
:
interface IByteCountable { // some descriptive name
int getByteCount();
}
然后从 LruCache
创建派生的 class,强制类型正确性:
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
我想知道是否可以在 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);
}
};
它存在吗?
更好的解决方案是将 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
.
如果方法是 public,请改用 getMethod
。
EDIT 评论指出这不会从超类型获取方法是正确的。如果你需要,你可以使用这个(它跳过 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;
}
您可以使用org.springframework.util.ReflectionUtils
public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes)
从 class 或 super class 获取方法。
我认为您要问的问题与您要解决的问题并不完全相同。使用 java 泛型,您可以通过以下方式安全地执行此类型:
您可以简单地创建一个界面,该界面具有 getByteCount()
:
interface IByteCountable { // some descriptive name
int getByteCount();
}
然后从 LruCache
创建派生的 class,强制类型正确性:
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