![](/img/trans.png)
[英]Using Java generics in an interface to enforce implementation of a method with the implementing type as a parameter
[英]Java: Get method with interface parameter with its implementation
我想調用具有參數接口的方法(使用反射) - 即:List 但具有 List 的實現。 例如:
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
Method method = Test1.class.getMethod("method", new Class[]{ArrayList.class});
}
public class Test1 {
public void method(List list) {
System.out.println("method");
}
}
}
我得到NoSuchMethodException
。 在這種情況下,我知道我得到了哪些參數,問題是當我不“靜態地”知道參數類型時,我想在一般情況下使用它。
getMethod 是否也可能返回具有接口作為參數的方法? 或者我必須寫我自己的“methodsearcher”
謝謝。
編輯:它要復雜得多。 我正在嘗試在我的程序中編寫類似“動態模塊化架構”的內容。 我有核心,它應該與其他模塊通信。 所以我在編程時不知道 params 類,但在運行時。
public Object processMessage(String target, String methodName, List<Object> params, Object returnNonExist) {
Module m = modules.get(target);
if (m == null) {
return returnNonExist;
} else {
Class[] paramsTypes = new Class[params.size()];
for (int i = 0; i < params.size(); i++) {
paramsTypes[i] = params.get(i).getClass();
}
}
try {
Method method = m.getClass().getMethod(methodName, paramsTypes);
Object result = method.invoke(m, params.toArray());
return result;
}
是不是更好?
我可能找到了解決方案 - 我必須編寫自己的“方法搜索器”,它尊重接口實現和超類。 它看起來像這樣:
public static Method findMethod(Object m, String methodName, Class[] paramsTypes) {
Method[] metody = m.getClass().getDeclaredMethods();
List<Method> sameNames = new ArrayList<Method>();
// filter other names
for (Method meth : metody) {
if (meth.getName().equals(methodName)) {
sameNames.add(meth);
}
}
// lets find best candidate
if (sameNames.isEmpty()) {
return null;
} else {
// filter other count of parameters
List<Method> sameCountOfParameters = new ArrayList<Method>();
for (Method meth : sameNames) {
if (meth.getParameterTypes().length == paramsTypes.length) {
sameCountOfParameters.add(meth);
}
}
if (sameCountOfParameters.isEmpty()) {
return null;
} else {
for (Method meth : sameCountOfParameters) {
// first one, which is suitable is the best
Class<?>[] params = meth.getParameterTypes();
boolean good = true;
for (int i = 0; i < params.length && good; i++) {
if (params[i].isInterface() && Arrays.asList(paramsTypes[i].getInterfaces()).contains(params[i])) {
//if i-th paramater type is Interface and we search method with its implementation
good = true;
continue;
} else {
// if we call it with subclass and parameter typ is superclass
if (paramsTypes[i].getSuperclass().equals(params[i])) {
good = true;
continue;
}
}
good = false;
}
if (good) {
return meth;
}
}
}
}
return null;
}
我在標准 getMethod 拋出“NoSuchMethodException”之后使用它(在大約 5% 的情況下,所以我不關心速度。
您應該使用List
類,而不是ArrayList
。
Method method = Test1.class.getMethod("method", new Class[]{List.class});
@radeczek 的精彩回答。 我將其擴展為適用於子類......
public Method findMethod(String name, Class<?>[] paramsTypes) {
Method[] methods = object.getClass().getMethods();
List<Method> sameNames = new ArrayList<Method>();
// filter other names
for (Method m : methods) {
if (m.getName().equals(name)) {
sameNames.add(m);
}
}
// lets find best candidate
if (sameNames.isEmpty()) {
return null;
} else {
// filter other count of parameters
List<Method> sameCountOfParameters = new ArrayList<Method>();
for (Method m : sameNames) {
if (m.getParameterTypes().length == paramsTypes.length) {
sameCountOfParameters.add(m);
}
}
if (sameCountOfParameters.isEmpty()) {
return null;
} else {
for (Method m : sameCountOfParameters) {
// first one, which is suitable is the best
Class<?>[] params = m.getParameterTypes();
boolean good = true;
for (int i = 0; i < params.length && good; i++) {
// Recurse into subclasses
good = findSubclass(paramsTypes[i],params[i]);
}
if (good) {
return m;
}
}
}
}
return null;
}
/**
* Recursive check for interfaces of superclasses.
*
* @param paramType
* @param param
* @return
*/
private boolean findSubclass(Class<?> paramType, Class<?> param) {
if (param.isInterface() && Arrays.asList(paramType.getInterfaces()).contains(param)) {
return true;
} else {
if (paramType.getSuperclass() != null) {
return findSubclass(paramType.getSuperclass(), param);
} else {
return false;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.