Java class with 2 generic parameters - java

I'm trying to crate my own thread safe event handling but I get E cannot be resolved to a type error on class decleration line below. How can I fix this?
Observers.java
public final class Observers<T extends EventHandler<E>> {
private CopyOnWriteArrayList<T> mListeners = new CopyOnWriteArrayList<T>();
public interface EventHandler<E> {
public void HandleEvent(Object sender, E e);
}
/*...*/
public void dispatchEvent(Object sender, E args) {
/*...*/
}
}
EventHandler.java
public interface EventHandler<E extends EventArgs> {
/* ... */
}

You've only actually declared a single type parameter in Observers. Try this:
public final class Observers<E extends EventArgs, T extends EventHandler<E>> {
Note that it looks highly odd for your Observers class to declare its own nested EventHandler interface while implementing the outer one - if you really need both of those, I would suggest you rename one of them.

Related

How to call interface field referring generic type?

Here is the case.
I have the interface with the field:
public interface SpecificAction extends Action{
String CONSTANT_FIELD = "Specific field";
}
And then I have the parametrized class with the method inside which I want to call my SpecificAction interface field:
public class Test<A extends Action>{
void someMethod(){
System.out.println(A.CONSTANT_FIELD); // there would be the "cannot resolve symbol
// CONSTANT_FIELD" message
}
}
Is there any way how I can call that interface field referring to generic type instead of the interface?
Interfaces define an "is-a" relationship type. They declare methods that should be implemented but not fields or any method-bodies.
What you need to do to get this working is to convert SpecificAction to an abstract class which may have default implemented methods and declare abstract methods (unimplemented).
EDIT: A solution (?)
class Test<A extends Action> {
private final A action;
public Test(A someAction) {
this.action = someAction;
}
void someMethod(){
System.out.println(action.getConstantField());
}
}
class SpecificAction extends Action {
public SpecificAction(String constantField) {
super(constantField);
}
// getConstantField inherited from parent class Action
}
// declaring this class abstract means it cannot be instantiated directly
abstract class Action {
private String constantField = "UNKNOWN";
public Action(String constantField) {
this.constantField = constantField;
}
public String getConstantField() {
return constantField;
}
public void setConstantField(String value) {
this.constantField = value;
}
}
If you call it from somewhere with something like
public static void main(String[] args) {
new Test<SpecificAction>(new SpecificAction("SpecificAction")).someMethod();
}
the output is:
SpecificAction
Process finished with exit code 0
i.e whatever you set the value to. You could refactor it to be constant within SpecificAction (a static final variable that gets passed to the super/parent constructor)
You need to extend your class from interface SpecificAction, not Action. Interface Action does not contains your field.
interface SpecificAction extends Action {
String CONSTANT_FIELD = "Specific field";
}
class Testt<A extends SpecificAction>{
void someMethod(){
System.out.println(A.CONSTANT_FIELD); // Fine
}
}

Cannot reference this before supertype constructer has been called + Consumer

I'm attempting to define a generic abstract class that handles the processing/retrying logic of the implementing class. I want all implementing classes to pass a "process" and "fail" function that is executed by the abstract class. The abstract class also holds retry attempt logic and some other generic boilerplate code that I would like to reuse.
Specifically, I have the following abstract class:
public abstract class EnvelopeDispatcher<T> {
protected Consumer<T> processFn;
protected Consumer<T> failFn;
private MetricsRegistry metricsRegistry;
public EnvelopeDispatcher(MetricsRegistry metricsRegistry, Consumer<T> processFn, Consumer<T> failFn) {
this.metricsRegistry = metricsRegistry;
this.processFn = processFn;
this.failFn = failFn;
}
protected void process(T envelope) {
//abstract processing logic calling processFn and failFn
}
}
And the following implementing class:
public class ActionEnvelopeDispatcher extends EnvelopeDispatcher<ActionEnvelope> implements Consumer<ActionEnvelope> {
public ActionEnvelopeDispatcher(MetricsRegistry metricsRegistry ) {
super(metricsRegistry, this::processEnvelope, this::failEnvelope)
}
#Override
public void accept(#NonNull ActionEnvelope envelopeToProcess) {
super.process(envelopeToProcess);
}
private void processEnvelope( ... ) {
//processing logic
}
private void failEnvelope( ... ) {
//failure case logic
}
}
When I attempt to call super while referencing this::processEnvelope and this::failEnvelope I get "Cannot reference this before supertype constructer has been called".
I understand why this is happening, but I'm not sure of the alternatives. Does anyone know how to get around this or a better implementation pattern?
What you could do is don't make the dispatcher abstract and create it using factory methods.
Something like this:
class EnvelopeDispatchers {
// factory method
public static EnvelopeDispatcher<ActionEnvelope> actionEnvelopeDispatcher(MetricsRegistry metricsRegistry) {
return new EnvelopeDispatcher(metricsRegistry,
EnvelopeDispatchers::processEnvelope,
EnvelopeDispatchers::failEnvelope);
}
private static void processEnvelope(ActionEnvelope env) {
//processing logic
}
private static void failEnvelope(ActionEnvelope env) {
//failure case logic
}
}

Issue with generics and <E extends ...>

I have two classes like this
public class Wire<E extends Electricity> implements Connection<E> {
private ArrayList<Inlet<E>> outlets = new ArrayList<Inlet<E>>();
public void outputToAll() {
for (Inlet<E> inlet : outlets){
inlet.addToStore(new Electricity(amountPer));
}
}
}
and
public abstract class Inlet<E> {
private E store;
public void addToStore(E inputObj){
this.store.add(inputObj);
}
}
Inlet doesn't have any errors, but Wire gives me the error that
The method addToStore(E) in the type Inlet is not applicable for the arguments (Electricity)
However, since in outputToAll E must extend electricity, so Inlet is at least Inlet, why does passing an Electricity object to addToStore not work?
And if the compiler isn't smart enough to know that this will work, what is a good workaround?
You don't need the Wire class to be generic for what it seems like you want to do.
If you just have:
public class Wire implements Connection<Electricity> {
private ArrayList<Inlet<Electricity>> outlets = new ArrayList<Inlet<Electricity>>();
public void outputToAll() {
for (Inlet<Electricity> inlet : outlets){
inlet.addToStore(new Electricity(amountPer));
}
}
...
}
This class will (likely, as I can't see the rest of it) work for subclasses of Electricity too, due to the Liskov substitution principle.

Checking `instanceof` while iterating through a loop

I have class structure where
public abstract class AbstractBuilding implements some non-relevant
interfaces for this question.
public abstract class AbstractAnimalBuilding extends AbstractBuiling
And small number of classes following this structure:
public class AnimalBuildingA extends AbstractAnimalBuilding
public class AnimalBuildingB extends AbstractAnimalBuilding
public class AnimalBuildingC extends AbstractAnimalBuilding
public class AnimalBuildingD extends AbstractAnimalBuilding
In a totally separate class I have the following method:
#FXML
private Button btnAnimalBuildingA;
#FXML
private Button btnAnimalBuildingB;
#FXML
private Button btnAnimalBuildingC;
#FXML
private Button btnAnimalBuildingD;
for (AbstractAnimalBuilding animalBuilding: animalBuildings){
if (animalBuilding instanceof AnimalBuildingA) {
changeButtonDisplay(btnAnimalBuildingA)
} else if (animalBuilding instanceof AnimalBuildingB){
changeButtonDisplay(btnAnimalBuildingB)
} else if (animalBuilding instanceof AnimalBuildingC) {
changeButtonDisplay(btnAnimalBuildingC)
} else if (animalBuilding instanceof AnimalBuildingD){
changeButtonDisplay(btnAnimalBuildingD)
//Do something specific here
}
}
private void changeButtonDisplay(Button buttonToChange){
button.setVisible(true);
}
Where animalBuildings is a Set<AbstractAnimalBuilding> containing any combination of AnimalBuildingX's.
Assuming the structure at the top needs to be kept (eg, AnimalBuildingX HAS to extend AbstractAnimalBuilding), what would be a better approach than the multiple if-then-else statements in determining what kind of building animalBuilding is?
Would it feasible to simply create a new Interface as outlined in this question and have each AnimalBuildingX implement it while still extending AbstractAnimalBuilding or is there a way I can do it using the structure I currently have.
This is difficult to answer in general without more context.
One possibility is to create an abstract method in AbstractBuilding and implement it differently in the subclasses.
Another possibility is to use the visitor pattern.
It depends on the action you want to take on behalf of the derived class type. If an action has to be taken which can be perfomed without the need, that the calling class knows the concrete implementation of AnimalBuilding the interface method is appropriate. This usually is the case if you can find a common method description which is implemented differently for each concrete class (e.g. getName()).
If you need to do specific actions dependent on the concrete class (e.g. AnimalBuildingA differs from AnimalBuldingB), you can implement the visitor pattern:
public abstract class AbstractAnimalBuilding {
...
public abstract void accept(AnimalBuildingVisitor v);
}
public interface class AnimalBuildingVisitor<T> {
public T visit(AnimalBuildingA a);
public T visit(AnimalBuildingB b);
...
}
The implementation of the accept-method usually is the one liner
return v.visit(this);
Then you create an implementation of the Abstract visitor which does the work you want to perform in the loop. The loop then looks like this
ConcreteAnimalBuildingVisitor v;
for (AbstractAnimalBuilding animalBuilding: animalBuildings)
animalBuilding.accept(v);
This way, the concrete class "identifies" itself to the concrete visior which then can perform the appropriate action.
You can keep your current structure and achieve what you desire by using generics:
First we need to define a generic handler interface:
public interface AnimalBuildingHandler<T extends AbstractAnimalBuilding> {
void handle(T type);
}
And then, in your own custom class, we can implement specific function for each types:
/* Here you can define all */
public void handleAnimalBuildingA(AnimalBuildingA animalBuildingA) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingA);
}
public void handleAnimalBuildingB(AnimalBuildingB animalBuildingB) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingB);
}
And then, we can create a magic handler class that implements the above AnimalBuildingHandler interface by mapping handlers to types just like this:
private Map<Class<? extends AbstractAnimalBuilding>, AnimalBuildingHandler<? extends AbstractAnimalBuilding>> handlersMapping;
{ /* default instance initializer */
handlersMapping = new HashMap<>();
handlersMapping.put(AnimalBuildingA.class, new AnimalBuildingHandler<AnimalBuildingA>() {
#Override
public void handle(AnimalBuildingA type) {
handleAnimalBuildingA(type);
}
});
handlersMapping.put(AnimalBuildingB.class, new AnimalBuildingHandler<AnimalBuildingB>() {
#Override
public void handle(AnimalBuildingB type) {
handleAnimalBuildingB(type);
}
});
}
#Override
public void handle(AbstractAnimalBuilding type) {
AnimalBuildingHandler abh = handlersMapping.get(type.getClass());
abh.handle(type);
}
And finally, the test method:
public <T extends AbstractAnimalBuilding> void test() {
List<T> allAnimalBuildings = new ArrayList<>();
allAnimalBuildings.add((T) new AnimalBuildingA());
allAnimalBuildings.add((T) new AnimalBuildingB());
for (AbstractAnimalBuilding aab : allAnimalBuildings) {
handle(aab);
}
}

Using Generalization properly

Suppose you have the following Interfaces
public interface Action {
public State execute(State state);
}
public interface State {
public Collection<Action> getPossibleActions();
}
And this method
public static Collection<State> getAllSuccessorStates(State state){
Collection<State> allSuccessors = new HashSet<>();
for (Action action: state.getPossibleActions()){
State successorState = action.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
A Concrete State could be for example a Chessboard and an Action the movement of a Piece on the board. Obviously the Chess-Actions need to know the concrete State class:
public class ChessAction implements Action {
#Override
public ChessState execute(ChessState state) {...}
}
Which is ofcourse not an allowed way of overriding execute. What would be the correct way of implementing this, so you can have concrete Actions, that operate on concrete States, which you can give as Arguments to getAllSuccessorStates?
I thought about Generics and also got answers pointing to Generics, but that brings about new Problems. If i write the Action class like this:
public interface Action<E extends State> {
public E execute(E state);
}
i will have the following Problem with ChessState class:
#Override
public Collection<Action<State>> getPossibleActions() {
Collection<Action<State>> actions = new ArrayList<>();
actions.add(new ChessAction());
return actions;
}
the line Actions.add causes the following error: The method add(Action) in the type Collection> is not applicable for the arguments (ChessAction)
Now i could declare Actions as
Collection<Action<ChessState>> actions = new ArrayList<>();
but that wont be a permitted return type.
You can use generics (needs java 1.5 or above):
public interface Action<T extends State> {
public T execute(T state);
}
public class ChessAction implements Action<ChessState> {
#Override
public ChessState execute(ChessState state) {...}
}
Hope that helps.
i found a satisfactory Solution now, which works correctly, doesnt need instanceof and yields no compile warnings:
public interface Action<E extends State<?>> {
public E execute(E state);
}
public interface State<E extends Action<?>> {
public Collection<E> getPossibleActions();
}
public static <A extends Action<S>, S extends State<A>> Collection<S> getAllSuccessorStates(S state){
Collection<S> allSuccessors = new HashSet<>();
for (A localAction: state.getPossibleActions()){
S successorState = localAction.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
Example of using getAllSuccessorStates (i forgo the implementation Details of the concrete classes here, but the Point should be apparent. You can use the method getAllSuccessorStates with any concrete State class, get Instances of this class in return collection and use them)
public class TestState implements State<TestAction> {...}
public class TestAction implements Action<TestState> {...}
public static void main(String[] args) {
TestState initialState = new TestState("1");
Collection<TestState> allSuccessorStates = getAllSuccessorStates(initialState);
for (TestState state: allSuccessorStates){
System.out.println(state.getStateStr());
}
}
This Question arose from the book "AI-A modern approache" by Stuart Russel and Peter Norvig, in case somebody who reads this book has the same Problem and searches for solutions. In the book the Action and State methods are inside a Problem Class, but i think in this way the OO-design is better.
Well, ChessState must have the same signature of execute as in the Action interface. If you require that ChessAction.execute accept only ChessState, you can write :
public class ChessAction implements Action {
#Override
public State execute(State state)
{
if (!(state instanceof ChessState))
throw new SomeException ();
ChessState cs = (ChessState) state;
...
}
}
You need to implement the same inherited method, and it will work since State is a super class for CheesState.
public class ChessAction implements Action {
#Override
public State execute(State state) {...}
}
Inside the execute method, you can use polymorph method (define in State and redefined ChessState), or you can cast to ChessState (ChessState s = (ChessState) state;), then use it as you need

Categories