Mutually recuresive type variable bounds

http://stackoverflow.com/questions/23248103/example-8-1-2-1-of-java-language-specificationmutually-recursive-type-variable

http://www.javaadvent.com/2013/12/type-safing-the-observer-with-mutually-recursive-bounds.html

A recursive type is a type that uses itself in its definition. The simplest example is the linked list:

class List<T> {
    T value;
    List<T> next;
}

Here, List<T> is recursively defined because it uses a List<T> in its own definition.

A type variable bound (Foo in <T> extends Foo) is recursive if it references itself, e.g.

class Bar<T extends Comparable<T>>

would mean that class Bar expects a parameter T that can be compared to a T, so T references itself in its own definition.

Mutual recursion between two things means that they reference each other in their definition. In this case, the definition of S uses T and the definition of T uses S, so their definition is mutually recursive.

interface ConvertibleTo<T> {
    T convert();
}
class ReprChange<T extends ConvertibleTo<S>,
                 S extends ConvertibleTo<T>> { 
    T t; 
    void set(S s) { t = s.convert();    } 
    S get()       { return t.convert(); } 
}

Example of typed Observer and Observable:
class Observable<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A>
interface Observer<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A>

class Baby extends Observable<Baby, Mother, String>
class Mother implements Observer<Baby, Mother, String>
class Dog extends Observable<Dog, Father, String>
class Father implements Observer<Dog, Father, String>

-------------------------------------------------

class StubException extends UnsupportedOperationException {
   private static final long serialVersionUID = 1L;
}

public class Observable<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A> {
   public void addObserver(O o) {
   throw new StubException();
}

protected void clearChanged() {
   throw new StubException();
}

-----------------------------------------------

/**
 * @author ciftimi
 * 
 */
public interface Observer<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A> {
   public void update(S o, A a);
}

----------------------------------------------

/**
 * @author ciftimi
 * 
 */
public class Baby extends Observable<Baby, Mother, String> {

 /*
 * The baby's name
 */
 private String name;

 public Baby(String name) {
     this.name = name;
 }

 /**
 * The event to notify about.
 */
 public void babyIsCrying() {
     setChanged();
     notifyObservers(name);
 }

}

---------------------------------------

/**
 * @author ciftimi
 * 
 */
public class Mother implements Observer<Baby, Mother, String> {

 /*
 * (non-Javadoc)
 * 
 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
 */
 @Override
 public void update(Baby baby, String babyName) {
     System.out.println("Let's change that diaper on " + babyName + "!");
 }

}