请问方法引用之后如何赋值
我现在想实现这种的效果
Beanutils.setProperty1(user, User::getName);
我参照网上的例子定义了一个接口类
@FunctionalInterface
public interface FunctionOperation<T> extends Serializable {
//这里只接收无参方法
Object get(T source);
//这个方法返回的SerializedLambda是重点
default SerializedLambda getSerializedLambda() throws Exception {
//writeReplace改了好像会报异常
Method write = this.getClass().getDeclaredMethod("writeReplace");
write.setAccessible(true);
return (SerializedLambda) write.invoke(this);
}
default String getImplClass() {
try {
return getSerializedLambda().getImplClass();
} catch (Exception e) {
return null;
}
}
default String getImplMethodName() {
try {
return getSerializedLambda().getImplMethodName();
} catch (Exception e) {
return null;
}
}
定义了实现方法
public static <T> Object setProperty1(Object object, FunctionOperation<T> a) {
try{
}catch (Exception e){
e.printStackTrace();
}
return object;
}
我在这里边如何操作,其他服务调用这个方法的时候
Beanutils.setProperty1(user, User::getName);
当我这么调用的时候,我希望在上边那个实现方法里给这个name赋值比如说 “aaa”,但是我使用反射的方法好像没有成功,想问一下一般都是如何处理
<!-------------------------------------------------------->
修改:
我没有表述清楚我的想法,我现在有两个方法,这两个方法我希望实现的功能是一样的
public static Object setProperty(Object object,String a,String b) {
Class target = object.getClass();
try{
PropertyDescriptor descriptor = new PropertyDescriptor(a,target);
Method method= descriptor.getWriteMethod(); //
method.invoke(object,"1");
PropertyDescriptor descriptor2 = new PropertyDescriptor(b,target);
Method method2= descriptor.getWriteMethod(); //
method2.invoke(object,"1");
}catch (Exception e){
e.printStackTrace();
}
return object;
}
public static <T> Object setProperty1(Object object, FunctionOperation<T> a,FunctionOperation<T> b) {
try{
}catch (Exception e){
e.printStackTrace();
}
return object;
}
我在controller调用了这两个方法
public static void main(String[] args) {
User user = new User();
user.setAge("1111");
System.out.println(user.toString());
try {
Beanutils.setProperty(user,"name","age");
//想采用这种方式
Beanutils.setProperty1(user, User::getName,User::getAge);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(user);
}
一种格式是
Beanutils.setProperty(user,"name","age")
传递字符串这种,我希望可以传递User::getName这种,也就是下边这样
Beanutils.setProperty1(user, User::getName,User::getAge);
我尝试在setProperty1方法里也是用setProperty方法里的那种invoke但是好像没有效果。就卡住了我也不知道该怎么处理了
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来后续的补充才算明白
setProperty1
只是为了设置默认的属性值,其实题主你之前写这个User::getName,User::getAge
对我影响太大了,我老想到get
操作去,你这个不是赋值,所以应该是set
操作嘛这个方法引用,其实就是
lambda
表达式嘛,方法引用只是快捷写法,那lambda
表达式其实就是把方法做了抽象而一个方法是需要关心输入和输出的,那
lambda
表达式也需要关注输入和输出。题主想要
setProperty1
方法和setProperty
效果一样,所以setProperty1
方法中的参数传入的lambda
表达式应该也要做到给属性赋值的操作。那这个
lambda
表达式的输入是什么?setProperty1
方法中能给到的是参数有object
对象以及默认的输入值"1"
,所以传入的lambda
表达式的输入就应该是object
和"1"
,返回可以为空,因为这个lambda
表达式里我只对某个属性做设置操作就可以了那我们
jdk
中提供了有没有根据两个参数做操作,但是返回void
的FunctionalInterface
呢?当然有的,那就是BiComsumer
之前提到
lambda
表达式就是一个方法的抽象,所以我们可以看到BiComsumer
这个方法的抽象要求有两个参数,然后返回void
,因此我们就可以这样来设计setProperty1
方法中后两个参数的传入当然
setProperty1
方法就应该改为最终直接调用为
当然现在这种写法是按照
set
方法直接做写入的,题主之前用的JavaBeans
的PropertyDescriptor
,如果要按照PropertyDescriptor
的方式写一个lambda
表达式,那就是另一种写法但是大体思路结构是类似的
看起来一样,不过你可以去试试,编译会报错的,在
new PropertyDescriptor
上,因为new PropertyDescriptor
显示的抛出了异常,而我们的BiConsumer
的accept
方法没有throws
异常,因此要改的话,就不能在用BiComusmer
了,需要自己写一个比如我们写一个
CustomBiComusmer
,和BiComusmer
类似,只是accept
方法抛出异常即可然后把
BiComsumer
换成我们的CustomBiConsumer
就可以啦,setProperty1
方法中的参数也记得改哦这样就可以了么?其实还可以再精炼一点,我们平常写方法都会公共方法提到一起,那
lambda
表达式作为方法的抽象,当然也可以做一次整合因为我们发现
consumerName
和consumerAge
非常接近,他们的差别只是参数传入的"name"
和"age"
的差距,其他都一样因此此时如果再把这种我们要处理的情况看成是一个方法,那根据我们之前说的,此时方法的输入应该是一个属性名,只有一个输入,输出是什么?那当然是我们要的
CustomBiConsumer
一个输入,一个输出的
FunctionalInterface
,在jdk
里有么?有!那就是
Function
所以我们就可以把
consumerName
和consumerName
提取出一个公共的方法,这个公共方法的抽象就是一个Function<String, CustomBiConsumer<User, String>>
它的实现写为
所以我们之前的
consumerName
和consumerName
就可以写做以上就是简单的想法把,感觉题主可能对于
lambda
表达式还不是很透彻,如果你能把后几个用例看明白,尤其是consumerFunction
看懂,估计也就没什么问题啦,仅供参考哈,债见ヾ( ̄▽ ̄)Bye~Bye~