2

I recently posted a question on SO (How do I use double dispatch to analyze intersection of graphic primitives?) in which one of the answers (which I have accepted) used generics including <P> and <R>. They aren't in the Oracle docs Java generics list but I have seen them used elsewhere (e.g. Generics overkill in visitor pattern ) - are they specific to the visitor pattern? And why are both super and extends used?

The code is:

public interface ShapeVisitor<P, R> { 
    R visitRect(Rect rect, P param);
    R visitLine(Line line, P param);
    R visitText(Text text, P param);
}

public interface Shape {
    <P, R> R accept(P param, ShapeVisitor<? super P, ? extends R> visitor);
    Shape intersectionWith(Shape shape);
}

public class Rect implements Shape {

    public <P, R> R accept(P param, ShapeVisitor<? super P, ? extends R> visitor) {
        return visitor.visitRect(this, param);
    }

    public Shape intersectionWith(Shape shape) {
        return shape.accept(this, RectIntersection);
    }

    public static ShapeVisitor<Rect, Shape> RectIntersection = new ShapeVisitor<Rect, Shape>() {
        public Shape visitRect(Rect otherShape, Rect thisShape) {
            // TODO...
        }
        public Shape visitLine(Line otherShape, Rect thisShape) {
            // TODO...
        }
        public Shape visitText(Text otherShape, Rect thisShape) {
            // TODO...
        }
    };
}

and I'd be grateful for

Community
  • 1
  • 1
peter.murray.rust
  • 37,407
  • 44
  • 153
  • 217

2 Answers2

3

The names P and R are just identifiers. Judging by how they're used, I think they mean "Parameter" and "Return Value", respectively.

Now, in the Shape.accept method, parameters can be made to be contra-variant, that's why you see super with P, and a return value co-variant, and that's why you see extends with R there.

Jordão
  • 55,340
  • 13
  • 112
  • 144
0

When you create a class:

public class MyComparable<R>{

    public boolean compare(R r1, R r2){
        // Implementation
    }
}

you are just indicating that you need to use two objects of the same Class.

to initialize that class you would use

List<String> strings = fillStrings();
int i = 1;
while(i < strings.size()){
    boolean comparePreviousWithThis = new MyComparable<String>().compare(strings.get(i-1),strings.get(i));
}

so you are only specifying the kind of relation that the objects of this class will have.

RamonBoza
  • 8,898
  • 6
  • 36
  • 48