以任何 setter 作为参数的方法
Method that takes any setter as a parameter
我有一个项目class
public class Item {
Long id;
String name;
Boolean isGood;
// getters and setters
}
我想声明一个方法,它可以将方法引用和一些值作为参数。
我试过的
public class Main {
public static void main(String[] args) {
Item item = new Item();
setLong(item::setId, 123L);
setBool(item::setGood, true);
setString(item::setName, "Foo Bar");
}
static void setLong(Consumer<Long> setter, Long o) {
setter.accept(o);
}
static void setBool(Consumer<Boolean> setter, Boolean o) {
setter.accept(o);
}
static void setString(Consumer<String> setter, String o) {
setter.accept(o);
}
}
但我想要类似的东西
set(Long.class, item::setId, 123L);
set(Boolean.class, item::setGood, true);
set(String.class, item::setName, "Foo Bar");
我该怎么做?
试试这个。
import java.util.function.Consumer;
public class SOQ_20220528
{
public static class Example
{
private Short a;
private Integer b;
private Long c;
public Example() {}
public Short getA() {
return this.a;}
public Integer getB() {
return this.b;}
public Long getC() {
return this.c;}
public void setA(Short a) {this.a = a;}
public void setB(Integer b) {this.b = b;}
public void setC(Long c) {this.c = c;}
public String toString() {
return this.a + " " + this.b + " " + this.c; }
}
public static void main(String[] args)
{
final Example instanceName= new Example();
final Short tuv = 1;
set(Short.class, instanceName::setA, Short.valueOf(tuv));
set(Integer.class, instanceName::setB, Integer.valueOf(2));
set(Long.class, instanceName::setC, Long.valueOf(3));
}
public static <T> void set(Class<T> clazz, Consumer<T> setter, T value)
{
setter.accept(value);
}
}
我们把我们想要使用的类型的 Class 作为第一个参数,然后我们把 setter 作为我们的第二个参数,最后,我们把我们想要的字面值对象作为我们的第三个参数进行调整。
第一个参数是必需的,因为在运行时会进行类型擦除。 Java 根本不在运行时保留类型,所以我们只需要传入 Class,它作为我们的运行时类型。
第二个参数是必需的,因为你需要一个setter来执行。但是,请注意我做了 instanceName::setA
而不是 Example::setA
。由于这是我们 提供 消费者使用的代码部分,因此我使用 instance 名称而不是 type 名称。很多时候它实际上是相反的(一个例子是静态方法)。
第三个参数是setter参数的实际值。我将 instanceName
的字段 a
设置为 Short
值 1
。 1
部分是我所说的第三个参数。
EDIT - 事实证明,对于这个特定示例,Class<T>
参数不是必需的。为了修改的简单性,我将保留它,但是是的,你可以在技术上有一个这样的方法头 - public static <T> void set(Consumer<T> setter, T value)
,然后你会像以前一样向这个方法提供参数,只是没有 class.
我有一个项目class
public class Item {
Long id;
String name;
Boolean isGood;
// getters and setters
}
我想声明一个方法,它可以将方法引用和一些值作为参数。
我试过的
public class Main {
public static void main(String[] args) {
Item item = new Item();
setLong(item::setId, 123L);
setBool(item::setGood, true);
setString(item::setName, "Foo Bar");
}
static void setLong(Consumer<Long> setter, Long o) {
setter.accept(o);
}
static void setBool(Consumer<Boolean> setter, Boolean o) {
setter.accept(o);
}
static void setString(Consumer<String> setter, String o) {
setter.accept(o);
}
}
但我想要类似的东西
set(Long.class, item::setId, 123L);
set(Boolean.class, item::setGood, true);
set(String.class, item::setName, "Foo Bar");
我该怎么做?
试试这个。
import java.util.function.Consumer;
public class SOQ_20220528
{
public static class Example
{
private Short a;
private Integer b;
private Long c;
public Example() {}
public Short getA() {
return this.a;}
public Integer getB() {
return this.b;}
public Long getC() {
return this.c;}
public void setA(Short a) {this.a = a;}
public void setB(Integer b) {this.b = b;}
public void setC(Long c) {this.c = c;}
public String toString() {
return this.a + " " + this.b + " " + this.c; }
}
public static void main(String[] args)
{
final Example instanceName= new Example();
final Short tuv = 1;
set(Short.class, instanceName::setA, Short.valueOf(tuv));
set(Integer.class, instanceName::setB, Integer.valueOf(2));
set(Long.class, instanceName::setC, Long.valueOf(3));
}
public static <T> void set(Class<T> clazz, Consumer<T> setter, T value)
{
setter.accept(value);
}
}
我们把我们想要使用的类型的 Class 作为第一个参数,然后我们把 setter 作为我们的第二个参数,最后,我们把我们想要的字面值对象作为我们的第三个参数进行调整。
第一个参数是必需的,因为在运行时会进行类型擦除。 Java 根本不在运行时保留类型,所以我们只需要传入 Class,它作为我们的运行时类型。
第二个参数是必需的,因为你需要一个setter来执行。但是,请注意我做了 instanceName::setA
而不是 Example::setA
。由于这是我们 提供 消费者使用的代码部分,因此我使用 instance 名称而不是 type 名称。很多时候它实际上是相反的(一个例子是静态方法)。
第三个参数是setter参数的实际值。我将 instanceName
的字段 a
设置为 Short
值 1
。 1
部分是我所说的第三个参数。
EDIT - 事实证明,对于这个特定示例,Class<T>
参数不是必需的。为了修改的简单性,我将保留它,但是是的,你可以在技术上有一个这样的方法头 - public static <T> void set(Consumer<T> setter, T value)
,然后你会像以前一样向这个方法提供参数,只是没有 class.