Hi I am trying to use Supplier and Consumer provided in Java8. I am trying to use a builder pattern where i can reuse the code every time i have to build my stanza/payload.
So I have a Stanzabuilder class where I am passing a class T (expecting any class)
public abstract class StanzaDataBuilder<T> {
final Supplier<T> instance;
StanzaDataBuilder(Supplier<T> instance) {
this.instance = instance;
}
public T build() {
return this.instance.get();
}
Now I am trying to build a stanza for one of the class (RetailProfile) For this, I wrote a builder class RetailProfileBuilder and extending StanzaBuilder and in that setting some values:
public class RetailProfileDataBuilder extends StanzaDataBuilder<RetailProfile>{
RetailProfileDataBuilder() {
super(RetailProfile::new);
}
public static RetailProfileDataBuilder of() {
RetailProfileDataBuilder rpf= new RetailProfileDataBuilder();
rpf.instance.get().setDomain("RetailBuffer");
return rpf;
}
When I debug and put system.out.println(rfb.instance.get().getDomain())
i can see the value is set , but when I am returning this rpf, value is null.
What I can see I am returning the obj <b>rpf</b>
which is a new object , hence value is setting to null. So I tried returning the instance instead
return (RetailProfileDataBuilder) rpf.instance;
Here I get an exception as :
java.lang.ClassCastException: package.RetailProfileDataBuilder$$Lambda$35/457597997 cannot be cast to package.RetailProfileDataBuilder
I am calling the builder class as :
RetailProfileDataBuilder rbdb= RetailProfileDataBuilder.of().build();
Here i am getting the value as null for the fields i set in RetailProfileDataBuilder class.
Any idea on how i can return the rpf object with the value??
Thanks for your time
rpf.instance.get()
create a new RetailProfile
each time you invoke, so you will see null
value instead of the value you set for previous instance
If you want to set some default value for every instance created by your Builder, you need to add some field to your builder class to maintains the state.
public class RetailProfileDataBuilder extends StanzaDataBuilder<RetailProfile>{
String domain;
RetailProfileDataBuilder() {
super(RetailProfile::new);
}
public static RetailProfileDataBuilder of() {
RetailProfileDataBuilder rpf= new RetailProfileDataBuilder();
domain = "RetailBuffer"; // Here you remember the `domain` value
return rpf;
}
@Override
public RetailProfile build() {
RetailProfile rp = super.build();
rp.setDomain(domain); // Here you pass the builder state to your new object
return rp;
}
}
rpf.instance
is a Supplier<RetailProfile>
, not a RetailProfileDataBuilder
, so you can't cast it to that type.
If you want to return the instance for which you set the domain, you can write:
public static RetailProfile of() {
RetailProfileDataBuilder rpf= new RetailProfileDataBuilder();
RetailProfile rp = rpf.instance.get();
rp.setDomain("RetailBuffer");
return rp;
}
If you want to return a RetailProfileDataBuilder
that always produces a RetailProfile
whose domain is set, you need to pass a different Supplier
to your constructor:
RetailProfileDataBuilder() {
super(() -> {
RetailProfile rp = new RetailProfile();
rp.setDomain("RetailBuffer");
return rp;
});
}
public static RetailProfileDataBuilder of() {
return new RetailProfileDataBuilder();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.