我正在处理一些自动生成的旧Java代码,它具有相同的方法名称和返回类型,但不实现任何接口。我想找到一些处理通话的常用方法。
例如,我有一组java类,A1,A2,都包含一个方法," getData()",getData方法将返回一组另一个类实例,如B1, B2。然后在B1,B2中,他们都有类似" getName"的方法。
我需要调用A.getData()。getName()。除了使用Java反射之外,还有什么方法可以处理这些场景吗?
class A1 {
B1 b;
B1 getData() {
return b;
}
}
class B1 {
String getName() {
return "myname in B1";
}
}
如果B1,B2实现了一些具有getName方法的接口(例如NameInterface),我可以使用如下的供应商:
A1 a1 = ...
A2 a2 = ...
doGetName(a1::getData);
doGetName(a2::getData);
void doGetName(Supplier<NameInterface> func) {
func.get().getName();
}
但不幸的是,B1,B2也是自动生成的遗留代码,我无法为它们分配接口。
我可以将B1,B2定义为供应商吗?如果有可能,如何定义它?
感谢。
答案 0 :(得分:2)
如果我可以声明您的方法(getData
和getName
)public
,以下内容适用于我。我没有使用任何供应商。
/**
* Requires that {@code a} has a public method getData that returns an object with a public getName method
*
* @param a
* @return a.getData().getName(); or null if the methods don’t exist
*/
public static String doGetName(Object a) {
try {
Class<?> aClass = a.getClass();
Method getDataMethod = aClass.getMethod("getData");
Object b = getDataMethod.invoke(a);
Class<?> bClass = b.getClass();
Method getNameMethod = bClass.getMethod("getName");
Object name = getNameMethod.invoke(b);
return name.toString();
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
System.out.println(e);
return null;
}
}
请致电
System.out.println(doGetName(new A1()));
请根据您的需要进行修改。
如果您的方法不公开,则可以使用getDeclaredMethod()
代替getMethod()
。
答案 1 :(得分:1)
我能看到的唯一选择是编辑A
类以直接返回包装数据的名称。
class A1 {
B1 b;
B1 getData() {
return b;
}
String getDataName() {
//Adding a null check here is probably smart, unless you know b != null
return getData().getName();
}
}
因为(您已暗示)每个A
类具有不同(但具体)的包装数据,您可以访问getName()
特定类型的B
方法A
}。您仍然需要将该方法复制粘贴到每个B1
中,因为B2
,A
等没有常见的超类型,但它不是结束世界,比不得不求助于反思要好得多。
从那里我们可以为interface DataWrapper {
Object getData(); //Could change the return type to a common ancestor if
//the legacy code is ever refactored
String getDataName();
}
添加一个通用界面:
A
并且有一个抽象类abstract class A implements DataWrapper {
//Other A stuff
}
class A1 extends A {...}
class A2 extends A {...}
实现,但将实现留给它的子类:
A
或者只是将这些方法放入abstract class A {
Object getData(); //Could change the return type to a common ancestor if
//the legacy code is ever refactored
String getDataName();
//Other stuff.
}
class A1 extends A {...}
class A2 extends A {...}
本身:
A a = ...
String name = a.getDataName();
根本不需要界面。
然后获取包装数据的名称没有问题。
<div class="wrapper" id="wrapper"></div>
<script type="application/javascript">
var x, i, y;
for(i = 0; i <= 10; i++){
y = i;
x = "<button class=btn_class"+y+"id=btn"+y+"onclick(alert(this.id);>Ukor</button>";
$("#wrapper").append(x);
}
$("button").on("click", function(){
alert(this.id);
});
</script>