This is related to java generic wild card.
I have interface like this.
public interface Processer<P, X> {
void process(P parent, X result);
}
An implementation like this.
public class FirstProcesser implements Processer<User, String> {
#Override
public void process(User parent, String result) {
}
}
And I'm using processer as this.
public class Executor {
private Processer<?, String> processer;
private int i;
public void setProcesser(Processer<?, String> processer) {
this.processer = processer;
}
private String generateString() {
return "String " + i++;
}
public <P> void execute(P parent) {
processer.process(parent, generateString());
}
public static void main(String[] args) {
Executor executor = new Executor();
executor.setProcesser(new FirstProcesser());
User user = new User();
executor.execute(user);
}
}
But here
public <P> void execute(P parent) {
processer.process(parent, generateString());
}
it gives compile error Error:(18, 27) java: incompatible types: P cannot be converted to capture#1 of ?
I need to understand why this give an error. also solution.
The wildcard basically means "I don't care which type is used here". In your case, you definitely do care though: the first type parameter of your processor must be the same as the P type in the execute method.
With the current code, you could call execute(1), which would try to call the FirstProcesser with an integer as argument, which obviously makes no sense, hence why the compiler forbids it.
The easiest solution would be to make your Executor class generic, instead of only the execute method:
public class Executor<P> {
private Processer<P, String> processer;
private int i;
public void setProcesser(Processer<P, String> processer) {
this.processer = processer;
}
private String generateString() {
return "String " + i++;
}
public void execute(P parent) {
processer.process(parent, generateString());
}
public static void main(String[] args) {
Executor executor = new Executor<User>();
executor.setProcesser(new FirstProcesser());
User user = new User();
executor.execute(user);
}
}
Because processor can have first type argument of anything. You may have assigned a Process<Foo, String> to it, and of course compiler will complain as it can be something different from P in your execute().
You may want to make your Executor a generic class:
class Executor<T> {
private Processer<T, String> processer;
public void setProcesser(Processer<T, String> processer) {
this.processer = processer;
}
public void execute(T parent) {
processer.process(parent, generateString());
}
}
and your main will look like:
Executor<User> executor = new Executor<User>();
executor.setProcesser(new FirstProcesser());
User user = new User();
executor.execute(user);
In response to comments:
There is no proper solution with proper use of Generics here, because what you are doing is contradicting: On one hand you say you do not care about first type argument of Processor (hence private Processor<?, String> processor), but on the other hand you DO really care about it (your execute). Compiler is simply doing its work right as it is absolutely legal for you to assign a Processor<Foo,String> to it.
If you don't really care about generics and is willing to suffer from poor design, then don't use generics.
Just keep Processor a raw type in Executor and suppress all unchecked warning:
i.e.
class Executor {
private Processor processor;
#SuppressWarnings("unchecked")
public void setProcessor(Processor<?, String> processor) {
this.processor = processor;
}
// your generic method does not do any meaningful check.
// just pass an Object to it
#SuppressWarnings("unchecked")
public void execute(Object parent) {
processor.process(parent, "");
}
}
And if it is me, I will go one step further:
Provide an Executor that is properly designed (e.g. calling it TypedExecutor). All new code should use the new, properly designed TypedExecutor. Original Executor is kept for sake of backward compatibility, and delegate its work to TypedExecutor.
Hence look like:
class TypedExecutor<T> {
private Processor<T, String> processor;
public void setProcessor(Processor<T, String> processor) {
this.processor = processor;
}
public void execute(T parent) {
processor.process(parent, "");
}
}
#SuppressWarnings("unchecked")
class Executor {
private TypedExecutor executor = new TypedExecutor();
public void setProcessor(Processor<?, String> processor) {
this.executor.setProcessor(processor);
}
public void execute(Object parent) {
this.executor.execute(parent);
}
}
Related
I want to create a series of Actions that do related things
public interface Action{
public void execute();
}
public class DatabaseAction implements Action{
public void execute(){}
}
public class WebAction implements Action{
public void execute(){}
}
public class EmailAction implements Action{
public void execute(){}
}
Generally speaking, users don't care about the details. They want all the actions to run and not worry about it.
But there's going to be some special cases where they only want to run some of the actions, and configure some of the actions.
And I suppose there could be cases where configuration is non-optional.
I figure a fluent interface is the most readable here.
// Executes all Actions - intended to be used in almost all cases
// I write to a database, call a web API, and send an email.
Actions.withAllDefaults().execute();
// I don't need to send an email and I need to configure the database
Actions.withAction(DATABASE_ACTION)
.withConfiguration(DatabaseAction.PORT, 9000)
.withAction(WEB_ACTION)
.execute();
It feels like I should be implementing some sort of factory but it's hard for me to actually translate that into code.
Consider using the Fluent Builder Pattern instead of trying to make your factory fluent.
C# uses fluent programming extensively in LINQ to build queries using "standard query operators".
This is C# implementation. It looks like this sample code can be converted to Java as special features of C# is not used.
So let's see an example. We start from an interface IFluent which allows to build your actions with settings:
public interface IFluent
{
IFluent WithAction(Action action);
IFluent WithConfiguration(KeyValuePair<string, object> configuration);
}
and this is Fluent class which implements IFluent interface:
public class Fluent : IFluent
{
private List<Action> actions;
public IFluent WithAction(Action action)
{
if (actions == null)
actions = new List<Action>();
actions.Add(action);
return this;
}
public IFluent WithConfiguration(KeyValuePair<string, object> configuration)
{
if (actions == null || actions.Count == 0)
throw new InvalidOperationException("There are no actions");
int currentActionIndex = actions.Count - 1;
actions[currentActionIndex].Set(configuration);
return this;
}
}
Then we create an abstract class for Action that should define behavior for derived classes:
public abstract class Action
{
public abstract Dictionary<string, object> Properties { get; set; }
public abstract void Execute();
public abstract void Set(KeyValuePair<string, object> configuration);
public abstract void Add(string name, object value);
}
And our derived classes would look like this:
public class DatabaseAction : Abstract.Action
{
public override Dictionary<string, object> Properties { get; set; }
= new Dictionary<string, object>()
{
{ "port", 0},
{ "connectionString", "foobarConnectionString"},
{ "timeout", 60}
};
public override void Execute()
{
Console.WriteLine("It is a database action");
}
public override void Set(KeyValuePair<string, object> configuration)
{
if (Properties.ContainsKey(configuration.Key))
Properties[configuration.Key] = configuration.Value;
}
public override void Add(string name, object value)
{
Properties.Add(name, value);
}
}
and EmailAction:
public class EmailAction : Abstract.Action
{
public override Dictionary<string, object> Properties { get; set; }
= new Dictionary<string, object>()
{
{ "from", "Head First - Object Oriented Design"},
{ "to", "who wants to learn object oriented design"},
{ "index", 123456}
};
public override void Execute()
{
Console.WriteLine("It is a email action");
}
public override void Set(KeyValuePair<string, object> configuration)
{
if (Properties.ContainsKey(configuration.Key))
Properties[configuration.Key] = configuration.Value;
}
public override void Add(string name, object value)
{
Properties.Add(name, value);
}
}
and WebAction:
public class WebAction : Abstract.Action
{
public override Dictionary<string, object> Properties { get; set; }
= new Dictionary<string, object>()
{
{ "foo", "1"},
{ "bar", "2"},
{ "hey", "hi"}
};
public override void Execute()
{
Console.WriteLine("It is a email action");
}
public override void Set(KeyValuePair<string, object> configuration)
{
if (Properties.ContainsKey(configuration.Key))
Properties[configuration.Key] = configuration.Value;
}
public override void Add(string name, object value)
{
Properties.Add(name, value);
}
}
The it is possible to call code like this:
Fluent actions = new Fluent();
actions.WithAction(new DatabaseAction())
.WithConfiguration(new KeyValuePair<string, object>("port", 1))
.WithAction(new EmailAction())
.WithConfiguration(new KeyValuePair<string, object>("to", "me"));
I have problem with understanding how Java wildcard works in one particular case. Let's say I have class which represents generic response
public class MyResponse<T> {
private final int httpCode;
private final String message;
private final T data;
}
and resolver for that:
public class ResponseResolver {
public void resolve(Either<AppError, MyResponse<?>> responseToResolve) {
//some logic
}
public void resolveOption(Option<MyResponse<?>> responseToResolve) {
//some logic
}
}
and service where response is resolved with resolver
public class FooService {
private final ResponseResolver responseResolver;
public FooService(ResponseResolver responseResolver) {
this.responseResolver = responseResolver;
}
public void resolveFoo() {
Either<AppError, MyResponse<Foo>> either = Option.of(new MyResponse<>(200, "message", new Foo())).toEither(AppError.ERROR);
responseResolver.resolve(either);
}
public void resolveOptionFoo() {
MyResponse<Foo> foo = new MyResponse<>(200, "message", new Foo());
responseResolver.resolveOption(Option.of(foo));
}
}
I do not understand why resolveOption method which is called in resolveFooOption is a proper way but in method with Either compiler complies that required type is Either<AppError, MyResponse<?> but provided Either<AppError, MyResponse<Foo>. Can anybody explain me why second case is invalid?
I have these two methods
private void saveBaseLineLatency(E2EResultShort e2EResultShort) {
LatencyHistogram latencyHistogram = getLatencyHistogram(e2EResultShort);
latencyDrillDownRepository.saveBaseLine(latencyHistogram);
saveLatencyTable(latencyHistogram);
}
private void saveFreshTestLatency(E2EResultShort e2EResultShort) {
System.out.println("log: before saveLatencyHistogram");
LatencyHistogram latencyHistogram = getLatencyHistogram(e2EResultShort);
latencyDrillDownRepository.save(latencyHistogram);
saveLatencyTable(latencyHistogram);
}
How can I refactor out their common code?
I thought to use Callable but its call() is parameterless.
Consumer is the interface you want. It's part of the new java.util.function package in Java 8, so this won't work if you're on an older version of Java. (The package also has a number of similar other interfaces, like a BiConsumer that takes two arguments, and interfaces for consuming various primitive types as well.)
So, your helper method would be something like:
private void doLatencyOperation (E2EResultShort newThing, Consumer<LatencyHistogram> consumer) {
LatencyHistogram lh = getLatencyHistogram(newThing);
consumer.accept(lh);
saveLatencyTable(lh);
}
and you could call it thusly
private void saveBaseLineLatency(E2EResultShort e2EResultShort) {
doLatencyOperation(e2EResultShort, (lh) -> latencyDrillDownRepository.saveBaseLine(lh));
}
Create an abstract class and move all the common code there.
public abstract class MyClass{
public MyClass(E2EResultShort result, latencyDrillDownRepository){
this.result = result;
}
public void execute() {
LatencyHistogram latencyHistogram = getLatencyHistogram(e2EResultShort);
callMe(latencyHistogram, latencyDrillDownRepository);
saveLatencyTable(latencyHistogram);
}
public abstract void callMe(LatencyHistogram latencyHistogram, latencyDrillDownRepository);
}`
Now in your method, create concrete MyClass:
private void saveFreshTestLatency(E2EResultShort e2EResultShort) {
System.out.println("log: before saveLatencyHistogram");
MyClass myClass = new MyClass(e2EResultShort, latencyDrillDownRepository){
public void callMe(LatencyHistogram latencyHistogram, latencyDrillDownRepository){
latencyDrillDownRepository.save(latencyHistogram);
}
}
myClass.execute();
}
I am getting a compilation error. I want my static method here to return a factory that creates and return Event<T> object. How can I fix this?
import com.lmax.disruptor.EventFactory;
public final class Event<T> {
private T event;
public T getEvent() {
return event;
}
public void setEvent(final T event) {
this.event = event;
}
public final static EventFactory<Event<T>> EVENT_FACTORY = new EventFactory<Event<T>>() {
public Event<T> newInstance() {
return new Event<T>();
}
};
}
Generic parameters of a class do not apply to static members.
The obvious solution is to use a method rather than a variable.
public static <U> EventFactory<Event<U>> factory() {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
}
The syntax is more concise in the current version of Java.
It is possible to use a the same instance of EventFactory stored in a static field, but that requires an unsafe cast.
You have:
public final class Event<T> {
...
public final static EventFactory<Event<T>> EVENT_FACTORY = ...
}
You cannot do this. T is a type that is associated with a specific instance of an Event<T>, and you cannot use it in a static context.
It's hard to give you good alternate options without knowing more about what exactly you are trying to do, as this is sort of an odd-looking factory implementation. I suppose you could do something like (put it in a method instead):
public final class Event<T> {
...
public static <U> EventFactory<Event<U>> createEventFactory () {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
};
}
And invoke it like:
EventFactory<Event<Integer>> factory = Event.<Integer>createEventFactory();
Or, if you don't want to be explicit (you don't really need to be, here):
EventFactory<Event<Integer>> factory = Event.createEventFactory();
Why don't you get rid of the whole static member of Event thing and either keep the factories separate, e.g.:
public final class GenericEventFactory<T> extends EventFactory<Event<T>> {
#Override public Event<T> newInstance() {
return new Event<T>();
}
}
And use, e.g., new GenericEventFactory<Integer>() where appropriate?
I have an ExecutorService that is used to handle a stream of tasks. The tasks are represented by my DaemonTask class, and each task builds a response object which is passed to a response call (outside the scope of this question). I am using a switch statement to spawn the appropriate task based on a task id int. It looks something like;
//in my api listening thread
executorService.submit(DaemonTask.buildTask(int taskID));
//daemon task class
public abstract class DaemonTask implements Runnable {
public static DaemonTask buildTask(int taskID) {
switch(taskID) {
case TASK_A_ID: return new WiggleTask();
case TASK_B_ID: return new WobbleTask();
// ...very long list ...
case TASK_ZZZ_ID: return new WaggleTask();
}
}
public void run() {
respond(execute());
}
public abstract Response execute();
}
All of my task classes (such as WiggleTask() ) extend DaemonTask and provide an implementation for the execute() method.
My question is simply; is this pattern reasonable? Something feels wrong when I look at my huge switch case with all its return statements. I have tried to come up with a more elegant lookup table solution using reflection in some way but can't seem to figure out an approach that would work.
Do you really need so many classes? You could have one method per taskId.
final ResponseHandler handler = ... // has many methods.
// use a map or array or enum to translate transIds into method names.
final Method method = handler.getClass().getMethod(taskArray[taskID]);
executorService.submit(new Callable<Void>() {
public Void call() throws Exception {
method.invoke(handler);
}
});
If you have to have many classes, you can do
// use a map or array or enum to translate transIds into methods.
final Runnable runs = Class.forName(taskClassArray[taskID]).newInstance();
executorService.submit(new Callable<Void>() {
public Void call() throws Exception {
runs.run();
}
});
You can use an enum:
public enum TaskBuilder
{
// Task definitions
TASK_A_ID(1){
#Override
public DaemonTask newTask()
{
return new WiggleTask();
}
},
// etc
// Build lookup map
private static final Map<Integer, TaskBuilder> LOOKUP_MAP
= new HashMap<Integer, TaskBuilder>();
static {
for (final TaskBuilder builder: values())
LOOKUP_MAP.put(builder.taskID, builder);
}
private final int taskID;
public abstract DaemonTask newTask();
TaskBuilder(final int taskID)
{
this.taskID = taskID;
}
// Note: null needs to be handled somewhat
public static TaskBuilder fromTaskID(final int taskID)
{
return LOOKUP_MAP.get(taskID);
}
}
With such an enum, you can then do:
TaskBuilder.fromTaskID(taskID).newTask();
Another possibility is to use a constructor field instead of a method, that is, you use reflection. It is much easier to write and it works OK, but exception handling then becomes nothing short of a nightmare:
private enum TaskBuilder
{
TASK_ID_A(1, WiggleTask.class),
// others
// Build lookup map
private static final Map<Integer, TaskBuilder> LOOKUP_MAP
= new HashMap<Integer, TaskBuilder>();
static {
for (final TaskBuilder builder: values())
LOOKUP_MAP.put(builder.taskID, builder);
}
private final int index;
private final Constructor<? extends DaemonTask> constructor;
TaskBuilder(final int index, final Class<? extends DaemonTask> c)
{
this.index = index;
// This can fail...
try {
constructor = c.getConstructor();
} catch (NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
// Ewww, three exceptions :(
public DaemonTask newTask()
throws IllegalAccessException, InvocationTargetException,
InstantiationException
{
return constructor.newInstance();
}
// Note: null needs to be handled somewhat
public static TaskBuilder fromTaskID(final int taskID)
{
return LOOKUP_MAP.get(taskID);
}
}
This enum can be used the same way as the other one.