I have the following class structure:
public interface Incoming<P extends Processor> {
void doSomething(P p);
}
public interface Processor<I extends Incoming> {
void process(I i);
}
public class MyIncoming implements Incoming<MyProcessor>
{
public void doSomething(MyProcessor p) { .. }
}
public class MyProcessor implements Processor<MyIncoming> {
public void process(MyIncoming i) { .. }
}
Now in another class I pass an Instance of MyIncoming that is supposed to initialize the type passed for the Processor it has defined in doSomething()?
Please help.
The first problem I see with your code is that you are using the raw types Incoming and Processor.
public interface Incoming<P extends Processor> {
void doSomething(P p); ^^
} that is a raw type!
One way to get rid of those raw types is to make both Incoming and Processor have two type parameters, but it's very complicated.
public interface Incoming<I extends Incoming<I, P>, P extends Processor<I, P>> {
void doSomething(P p);
}
public interface Processor<I extends Incoming<I, P>, P extends Processor<I, P>> {
void process(I i);
}
Now to your actual question. You've said that for each concrete implementation of Incoming you have a specific instance of Processor, and for a variable t of type Incoming, you want to be able to find out that instance x and call x.process(t);. I'm sure that this can be done with reflection, but I can't see the point. You can just make getProcessor a method of Incoming.
public interface Incoming<I extends Incoming<I, P>, P extends Processor<I, P>> {
void doSomething(P p);
P getProcessor();
}
Now you can write concrete implementations.
public class MyIncoming implements Incoming<MyIncoming, MyProcessor>
{
private static final MyProcessor PROCESSOR = new MyProcessor();
#Override
public void doSomething(MyProcessor p) { }
#Override
public MyProcessor getProcessor() { return PROCESSOR; }
}
public class MyProcessor implements Processor<MyIncoming, MyProcessor> {
#Override
public void process(MyIncoming i) { }
}
Now, if you have a generic class
class A<I extends Incoming<I, P>, P extends Processor<I, P>>
and, within A, you have a variable i of type I, you can do
i.getProcessor().process(i);
This works, but personally I think circular dependencies of the form TypeA<B extends TypeB> / TypeB<A extends TypeA> are unnecessarily convoluted, and the generics here actually work against you. It may preserve your sanity if you just make Incoming and Processor non-generic interfaces and use casting where necessary.
Related
I have the following class:
public abstract class A<T extends Event> {
void onEvent(T event);
}
and a Class<? extends Event> clazz object. How can I create an anonymous subclass of A with the same generic type parameter as my class object? In other words, how can I get the type from my class object and pass it into a new subclass of A?
Something like this:
new A<clazz.getType()>() {
#Override
public void onEvent(clazz.getType() event) {}
}
Java is a compiling language so you cannot dynamically change the class type so we have to define if blocks to change the type as per the data.
Your main Event class:
public class Event {}
The A class which get the type of class
public abstract class A<T extends Event> {
void onEvent(T t){};
}
Sample inherited class
public class Sample extends Event {}
Simple implementation
Sample sample = new Sample();
if (sample instanceof Sample) {
A<Sample> a = new A<Sample>() {
#Override
public void onEvent(Sample t) {
System.out.println(t.toString());
}
};
// Simple implementation
a.onEvent(sample);
}
Requirements
I am trying to write an Observer / Observable pair of classes. I want to parametrize the Observer so that a type safe update call is possible. Imagine this version:
class View implements Observer<Model> {
#Override
public void update(Model model) { render(model); } // no casting:)
}
Instead of this version that needs casting:
class View implements Observer {
#Override
public void update(Object model) { render((Model) model); } // casting:(
}
Attempt
Here's what I have so far. My Observer interface:
public interface Observer<T extends Observable> {
public void update(T observable);
}
and my Observable abstract class:
import java.util.List;
public abstract class Observable {
private List<Observer<? extends Observable>> observers;
public Observable() {
System.out.println(this.getClass());
}
public void addObserver(Observer<? extends Observable> obs) {
observers.add(obs);
}
public void removeObserver(Observer<? extends Observable> obs) {
observers.remove(obs);
}
protected <E extends Observable> void updateObservers(E self) {
for (Observer<? extends Observable> obs : observers) {
obs.update(self); // <-------------------- COMPILER ERROR!!!
}
}
}
Problem
The line labeled "COMPILER ERROR" has a problem with the .update():
The method update(capture#4-of ? extends Observable) in the type Observer is not applicable for the arguments (E)
So even though the self argument passed to update() is of type E extends Observable, it does not satisfy the interface method signature update(T observable); where T extends Observable. Why is that? I really expected those to be compatible.
Is there I can fix this to meet my requirements?
Thanks.
Use
import io.reactivex.Observable;
instead of
import java.util.Observable;
Why is that? I really expected those to be compatible.
Because the function public void update(T observable); has the same generic argument T as the Observer<T extends Observable> class, which means that it's argument type should be the same as the type of the reference variable which will invoke the update() function.
While, when you try to use the wildcard ? then the type of the variable obs is Observer<? extends Observable> which could be any different class that extends Observable than the type of the method arguments which is E.
Is there I can fix this to meet my requirements?
Yes, using the Self Bound / Recursive Generics, a concrete example is the Class Enum<E extends Enum<E>>, to understand this concept you can take a look at the See also section below.
So, your Observable will be something like:
import java.util.List;
public abstract class Observable<T extends Observable<T>> {
private List<Observer<T>> observers;
public Observable() {
System.out.println(this.getClass());
}
public void addObserver(Observer<T> obs) {
observers.add(obs);
}
public void removeObserver(Observer<T> obs) {
observers.remove(obs);
}
protected void updateObservers(T self) {
for (Observer<T> obs : observers) {
obs.update(self);
}
}
}
The Observer interface:
public interface Observer<T extends Observable<T>> {
public void update(T observable);
}
The View class:
class View implements Observer<Model> {
#Override
public void update(Model model) { render(model); }
}
Assuming that your Model class should be something like this:
public class Model extends Observable<Model>{
}
See also:
Java Enum definition
Self-bounding generics
Java - Interface extending itself
What would be the use of accepting itself as type arguments in generics
Problem
As per #hexafraction's commentary,
The Observable's List of the Observers is parametrized by any subclass of Observer (wildcard <? extends Observer>). This does not play nice with Observer<T extends Observable>'s update(T observable) method, which is expecting exactly the type of Observable which the Observer was parametrized by.
Here's a counterexample: class A extends Observable, class B extends Observable, class A1 extends A. The wildcard for obs would allow an Observer to be assigned to obs, and in that case calling obs.update() with an instance of A1 would be invalid.
Solution
The solution is to parametrize the Observable class as well, so that the List contents are constrained correctly for the Observer update() method:
public abstract class Observable<E> {
private List<Observer<E>> observers;
public Observable() {
observers = new ArrayList<>();
}
public void addObserver(Observer<E> obs) {
observers.add(obs);
}
public void removeObserver(Observer<E> obs) {
observers.remove(obs);
}
protected void updateObservers(E self) {
for (Observer<E> obs : observers) {
obs.update(self);
}
}
}
And the Observer parametrized by its own T:
public interface Observer<T> {
public void update(T observable);
}
If you need type constraints such that Observers may only observe Observables, and/or Observables may only send Observables to Observer updates, then use these class signatures:
public interface Observer<T extends Observable<T>> { ... }
public abstract class Observable<E extends Observable<E>> { ... }
The class bodies and behaviors are unaffected, but the compiler will complain if Observers and Observables are bound to anything but each other.
Usage
Parametrize an Observer (View) by the Observable (Model):
class View implements Observer<Model> {
#Override
public void update(Model model) { render(model); } // no casting:)
}
Parametrize an Observable (Model) by itself and call updateObservers():
class Model extends Observable<Model> {
public void doStuff() {
//...
updateObservers(this);
}
}
Change the Observer interface like below :
public interface Observer<T extends Observable> {
public <E extends Observable> void update(E observable);
}
I do have an abstract class with an delegation interface defined:
public abstract class MyAbstractClass extends AsyncLoader {
public interface MyAbstractClassDelegate<M> {
//The parameter in this method should be the concrete subtype of MyAbstractClass
public M performThisCall(MyAbstractClass concreteSubclassOfAbstractClass);
}
private MyAbstractClassLoaderDelegate delegate;
...
}
The Problem is, I do not want the delegate parameter to be MyAbstractClass, instead it should be the concrete subclass. Why? Because the implementation of the delegate needs the concrete subclass for further handling and I don't want to cast it...
I know I could define an Interface in each subclass, but it'll look the same in every subclass except for the parameter type
EDIT
Here is the perfect solution solving exactly what I wanted. Great thanks!
public abstract class MyAbstractClass {
public interface MyAbstractClassDelegate<M, Subtype extends MyAbstractClass> {
public M myMethod(Subtype t);
}
}
Is this possible with java 6 and if yes - how?
My solution would be:
public final class Example<T extends Example<T>> {
public interface Interface<M, Subtype extends Interface<M, Subtype>> {
public M myMethod(Subtype t);
}
}
You have no access to the generic from the outer class inside the interface (because the interface is static) so you have to declare it again.
If you use your interface you get something like this:
private static class Impl1 implements Interface<String, Impl1> {
#Override
public String myMethod(final Impl1 t) {
return null;
}
}
I don't know if it will help but here is my complete example:
public final class Example<M, T extends Example.Delegate<M, T>> {
public interface Delegate<M, Subtype extends Delegate<M, Subtype>> {
public M myMethod(Subtype t);
}
private T delegate;
private static class Impl1 implements Delegate<String, Impl1> {
#Override
public String myMethod(final Impl1 t) {
return null;
}
}
public static void main(String[] args) {
Example<String, Impl1> example = new Example<>();
example.delegate = new Impl1();
example.delegate.myMethod(example.delegate); //works but whout?
}
}
What you could do is to give your abstract class a type parameter with the concrete subclass, similar to the way Java's Enum does it.
Something along the lines of this:
public abstract class MyAbstractClass<S extends MyAbstractClass<S>> extends AsyncLoader {
public interface MyAbstractClassDelegate<M, S> {
public M performThisCall(S concreteSubclassOfAbstractClass);
}
...
(Working in Java)
I have an abstract class with generic typing throughout the whole class:
public abstract class ConnectionProcessor<T>
{
public void process()
{
for (List<T> resultsPage : connection)
{
processPage(resultsPage);
}
}
protected abstract void processPage(List<T> resultsPage);
}
I have another class that extends said abstract class, with the following declaration:
public class AlbumProcessor<Album> extends ConnectionProcessor
{
#Override
protected void processPage(List resultsPage)
{
//Do stuff here specific to Album
}
}
This declaration works fine, but in processPage I want to do Album-specific things, and I try to avoid casting when I don't need to use it. I would PREFER this to be the method declaration:
protected void processPage(List<Album> resultsPage)
But this doesn't meet the requirements for overriding processPage from ConnectionProcessor. Why is this? How can I get the desired behavior? I would think that in AlbumProcessor I could just plug in <Album> everywhere ConnectionProcessor has <T>, but that just isn't the case.
Try
//extend prameterized version of ConnectionProcessor<T> with Album as actual type argument
public class AlbumProcessor extends ConnectionProcessor<Album> {
instead of
public class AlbumProcessor<Album> extends ConnectionProcessor {
When you do the above you are exteding the raw version of the generic type ConnectionProcessor<T> and introducing a new formal type parameter - Album (like T) which is not an actual type argument in that case.
That's because you didn't bind your super class Generic type T to Album.
Rather, this is what you should do:
public class AlbumProcessor extends ConnectionProcessor<Album>
So, when you'll override your method processPage, (using an IDE), it will generate code as follows:
#Override
protected void processPage(List<Album> resultsPage)
{
//Do stuff here specific to Album
}
public class AlbumProcessor extends ConnectionProcessor<Album>
Try: -
public class AlbumProcessor extends ConnectionProcessor<Album>
{
#Override
protected void processPage(List<Album> resultsPage)
{
//Do stuff here specific to Album
}
}
You need to bind your super class with the type you want to give as a type parameter to your List in your method declaration..
How bout something more like this.
import java.util.List;
public abstract class ConnectionProcessor<T>
{
public void process()
{
System.out.println("Hello");
}
protected abstract void processPage(List<? extends T> resultsPage);
}
...
public class ProcessorImpl extends ConnectionProcessor<Album> {
protected void processPage(List<? extends Album> resultsPage) {
for(Album result : resultsPage){
System.out.println(result.getAlbumName());
}
}
}
...
public class Album {
public String getAlbumName(){
return "Sweet Smooth SOunds of the 70's";
}
}
I have a base class that has an abstract getType() method. I want subclasses to be able to implement this method and provide the actual class to use.
In code, something like the following:
public abstract class A {
public static interface Tile;
protected abstract Class<Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected abstract Class<A.Tile> getTileClass() {
MyTile t = new MyTile(); // WORKS
return MyTile; // ERROR HERE
}
}
The problem here is that I get "MyTile cannot be resolved" in the line marked. So I'm trying to return this instead:
return new MyTile().getClass()
but now Eclipse tells me:
Type mismatch: cannot convert from
Class<capture#1-of ? extends B.MyTile>
to Class<A.Tile>
which I'm not even sure if there's maybe a bug in Eclipse here top (capture#1?).
Next, I'm giving up on interfaces and trying to use an abstract base Tile class. With some help from Eclipse, I end up with the following code that seems to compile:
public abstract class A {
public static abstract class Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile exends A.Tile { }
#Override
protected abstract Class<? extends A.Tile> getTileClass() {
return new MyTile().getClass(); // WORKS
return MyTile; // "Cannot be resolved"
}
}
So I basically seem to have three questions:
1) Is it possible to get this to work with A.Tile being an interface?
2) When using a base class, is Class<? extends X> really the correct way to go?
3) And how can I return my nested B.MyTile class reference from inside the method? Having to do new MyTile().getClass() can't be right, can it?
Generics and covariant type overriding do not work very well together. You have to explicitly declare getTileClass() as returning a class that can be a subclass of A.Tile.
You also can access the class object of MyTile without instanciating it, with MyTile.class.
Try this instead:
public abstract class A {
public static interface Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
Even better would be to make A generic. You still have to use extends in the class type definition, but you can be a bit more specific:
public abstract class A<T extends A.Tile> {
public static interface Tile;
protected abstract Class<? extends T> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
public abstract class A {
public static interface Tile {};
// I return something that is-a Tile
protected abstract Tile getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected abstract Tile getTileClass() {
return new MyTile();
}
}
No need for generics, you just want to say that you return a Tile or Tile subclass.
Incidentally, a public static interface in a class is a "code smell"; either make it protected, so only subclasses of A can implement Tile, or put it in its own top-level interface. Putting in a but allowing anyone to implement it sends a mixed message.