Generics Perplexed

Apologizing for the general headline, I can't think of a way to explain this.

I would like to simulate a scenario in which the system provides funds to users who are associated with policies that apply to requests for these objects.

public interface Facility { public List<Policy> getPolicies(); } public interface Policy { public void apply(Facility facility, Request request); } public interface Request { } 

But the request can be reasonable only for a certain type of object, and the policy can really be applied only to the type of object and the type of request specific to this type of object.

 public interface Facility<F extends Facility<F>> { public List<Policy<F, ? extends Request<F>>> getPolicies(); } public interface Policy<F extends Facility<F>, R extends Request<F>> { public void apply(F facility, R request); } public interface Request<F extends Facility<F>> { } 

But I would also like to be able to specify policies in general so that they can be applied to any Facility supertype.

 public interface Facility<F extends Facility<F>> { public List<Policy<? super F, ? extends Request<F>>> getPolicies(); } 

But in fact, you only want to request policies that apply to a specific type of request for the object.

 public interface Facility<F extends Facility<F>> { public <R extends Request<F>> List<Policy<? super F, R>> getPolicies(); } 

My problem is that now I am so confused with all generics, and I canโ€™t even create a policy class that applies to all Equipments that would be something like this if it were legal

 public class GeneralPolicy implements Policy<T extends Facility<T>, Request<T>> 

How do I make it possible to associate object types, policies, and queries in a way that makes sense as described above? Iโ€™m sure that people will ask for clarification, I have struggled with this for so long that I probably donโ€™t explain anything, or I donโ€™t see the obvious moment at all.

+4
source share
1 answer

If I read this correctly, then what you really want to do is get all the policies that work for R.

 public interface Facility<F extends Facility<F>> { public <R extends Request<F>> List<Policy<? super F, R>> getPolicies(); } 

Unfortunately, due to type erasure you cannot. At run time, the compiler does not know what R.

However, you can pass the class to:

 public interface Facility<F extends Facility<F>> { public <R extends Request<F>> List<Policy<? super F, R>> getPolicies(Class<R> requestClass); } 

Then the policy will also need to return its request type:

 public interface Policy<F extends Facility<F>, R extends Request<F>> { public void apply(F facility, R request); public Class<R> getRequestClass(); } 

Then, the implementation of the object may contain a list of available policies, check if the type of policy request matches the actual type of request, and returns this subset.

For global policies, a policy can return Request.class. For specific, MyRequest.class.

Also, I would say that Facility (at least the way you are there) does not need to be generalized, and that will make the code a lot easier.

+4
source

All Articles