在java中将对象方法指定为参数
我想创建一些实用方法,我希望它能够在不同的对象上工作,只要它们能够提供一个读/写的整数属性 我知道“标准”方法是:在java中将对象方法指定为参数,java,generics,methods,delegates,Java,Generics,Methods,Delegates,我想创建一些实用方法,我希望它能够在不同的对象上工作,只要它们能够提供一个读/写的整数属性 我知道“标准”方法是: 声明一些接口IProvidesAccessToInteger,该接口具有setInteger和getInteger 声明MyUtility.doSomethingWonderful(IProvidesAccessToInteger obj) 调用obj.setInteger和obj.getInteger 但这有一个非常严重的缺点,那就是它需要所有我想要MyUtility使用的类的合
IProvidesAccessToInteger
,该接口具有setInteger
和getInteger
李>
MyUtility.doSomethingWonderful(IProvidesAccessToInteger obj)
obj.setInteger
和obj.getInteger
MyUtility
使用的类的合作,不仅如此,即使某些类想要合作MyUtility
也只能.doSomethingWonderful()
到该类的一个预定字段
我正在寻找一些语法来支持类似于MyUtility.doSomethingWonderful(T obj,Method getter,Method setter)
的东西,可能会以某种方式使用泛型来指定要求obj
有两个方法可以设置并设置一个整数,并且可以在obj
的实例上调用它们
对不需要对象的静态方法执行类似操作也可能很有趣
更新:
正如我被指向反射一样,我想澄清一下,我知道使用反射可以完成相近的事情
然而,由于我不需要在运行时解析实际的接口,我希望JAVA有某种方式来指定某种“接口实现映射”,这样,如果我的需求是一个具有两种方法的对象int?()
和void?(int)
,我可以指定类似.doSomethingWonderful(?obj)
并对具有int getInt()
和void setInt(int)
的某个object1调用一次,对具有int getIntValue()
和void setIntValue(int)的某个其他object2调用一次
通过在调用中指定object
通过getInt
满足getInteger
的要求,并通过setInt
满足setInteger
的要求,依此类推。可能使用类似于“.doSomethingWonderful((?)object1)的调用语法
至少在理论上,我认为应该可以在编译时完成所有工作,而不需要任何运行时反射
也许匿名接口会给它起一个正确的名字
也就是说,我接受通过反射的运行时解决方案也可能是一种解决方案。泛型无法做到这一点 你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
final Method getter = in.getClass().getMethod("get" + upperCased);
final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
我假设您使用的是int
而不是Integer
,在后一种情况下,您需要稍微更改代码
您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码
编辑
Op希望将方法分解为三个重载方法:
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
}
public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final Method getter = in.getClass().getMethod(getterName);
final Method setter = in.getClass().getMethod(setterName);
doSomethingWonderful(in, getter, setter);
}
public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
你不能用泛型来做这件事 你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
final Method getter = in.getClass().getMethod("get" + upperCased);
final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
我假设您使用的是int
而不是Integer
,在后一种情况下,您需要稍微更改代码
您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码
编辑
Op希望将方法分解为三个重载方法:
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
}
public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final Method getter = in.getClass().getMethod(getterName);
final Method setter = in.getClass().getMethod(setterName);
doSomethingWonderful(in, getter, setter);
}
public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
你不能用泛型来做这件事 你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
final Method getter = in.getClass().getMethod("get" + upperCased);
final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
我假设您使用的是int
而不是Integer
,在后一种情况下,您需要稍微更改代码
您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码
编辑
Op希望将方法分解为三个重载方法:
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
}
public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final Method getter = in.getClass().getMethod(getterName);
final Method setter = in.getClass().getMethod(setterName);
doSomethingWonderful(in, getter, setter);
}
public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
你不能用泛型来做这件事 你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
final Method getter = in.getClass().getMethod("get" + upperCased);
final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
我假设您使用的是int
而不是Integer
,在后一种情况下,您需要稍微更改代码
您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码
编辑
Op希望将方法分解为三个重载方法:
public void doSomethingWonderful(final Object in, final String fieldName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
}
public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final Method getter = in.getClass().getMethod(getterName);
final Method setter = in.getClass().getMethod(setterName);
doSomethingWonderful(in, getter, setter);
}
public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//to invoke getter
final int val = (int) getter.invoke(in);
//to invoke setter
setter.invoke(in, val);
}
你的接受者和接受者是很好的反省范例。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。您的getter和setter是非常典型的反射。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。您的getter和setter是非常典型的反射。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。您的getter和setter是非常典型的反射。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。最接近您描述的是Java 8。您仍然需要接口,但调用者不需要关心它们,更好的是,对于典型的t