Skip to content

Instantly share code, notes, and snippets.

@esfand
Forked from rklemme/FailedApproach.java
Created April 9, 2012 03:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esfand/2341275 to your computer and use it in GitHub Desktop.
Save esfand/2341275 to your computer and use it in GitHub Desktop.
Sample code for dealing with self conscious parametrized types
// Source: http://www.velocityreviews.com/forums/t745036-mixing-self-conscious-parametrized-types-with-inheritance.html
package generics2;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Base comparable class with "type self consciousness".
*/
class BaseC implements Comparable<BaseC> {
private final int key;
private final int pos;
public BaseC(int key, int pos) {
this.key = key;
this.pos = pos;
}
public int getKey() {
return key;
}
public int getPos() {
return pos;
}
@Override
public int compareTo(BaseC o) {
return getKey() - o.getKey();
}
@Override
public String toString() {
return getClass().getSimpleName() + " [key=" + key + ", pos=" + pos + "]";
}
}
/**
* Non final sub class which must propagate the typing scheme in order to be
* extensible.
*/
class SubC extends BaseC implements Comparable<SubC> {
public SubC(int key, int pos) {
super(key, pos);
}
public int getK() {
return getKey();
}
@Override
public int compareTo(SubC o) {
final int cmp = getK() % 3 - o.getK() % 3;
return cmp == 0 ? getK() - o.getK() : cmp;
}
}
/**
* Final sub class which does not need a type parameter any more since there are
* no sub classes.
*/
final class FinalC extends SubC implements Comparable<FinalC> {
public FinalC(int key, int pos) {
super(key, pos);
}
public int getX() {
return getKey();
}
@Override
public int compareTo(FinalC o) {
final int cmp = getX() % 2 - o.getX() % 2;
return cmp == 0 ? getPos() - o.getPos() : cmp;
}
}
public final class FailedApproach {
private static final int ITEMS = 5;
public static void main(String[] args) {
final SortedSet<BaseC> s1 = new TreeSet<BaseC>();
for (int i = 0; i < ITEMS; ++i) {
final BaseC c = new BaseC(i, ITEMS - i);
s1.add(c);
}
System.out.println(s1);
final SortedSet<SubC> s2 = new TreeSet<SubC>();
for (int i = 0; i < ITEMS; ++i) {
final SubC c = new SubC(i, ITEMS - i);
s2.add(c);
}
System.out.println(s2);
final SortedSet<FinalC> s3 = new TreeSet<FinalC>();
for (int i = 0; i < ITEMS; ++i) {
final FinalC c = new FinalC(i, ITEMS - i);
s3.add(c);
}
System.out.println(s3);
}
}
package generics;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Base comparable class with "type self consciousness".
*
* @param <SC>
* our own type.
*/
class BaseC<SC extends BaseC<?>> implements Comparable<SC> {
private final int key;
private final int pos;
public BaseC(int key, int pos) {
this.key = key;
this.pos = pos;
}
public int getKey() {
return key;
}
public int getPos() {
return pos;
}
@Override
public int compareTo(SC o) {
return getKey() - o.getKey();
}
@Override
public String toString() {
return getClass().getSimpleName() + " [key=" + key + ", pos=" + pos + "]";
}
}
/**
* Non final sub class which must propagate the typing scheme in order to be
* extensible.
*
* @param <SC>
* out own type.
*/
class SubC<SC extends SubC<?>> extends BaseC<SC> {
public SubC(int key, int pos) {
super(key, pos);
}
public int getK() {
return getKey();
}
@Override
public int compareTo(SC o) {
final int cmp = getK() % 3 - o.getK() % 3;
return cmp == 0 ? getK() - o.getK() : cmp;
}
}
/**
* Final sub class which does not need a type parameter any more since there are
* no sub classes.
*/
final class FinalC extends SubC<FinalC> {
public FinalC(int key, int pos) {
super(key, pos);
}
public int getX() {
return getKey();
}
@Override
public int compareTo(FinalC o) {
final int cmp = getX() % 2 - o.getX() % 2;
return cmp == 0 ? getPos() - o.getPos() : cmp;
}
}
public final class SelfConsciousnessTest {
private static final int ITEMS = 5;
public static void main(String[] args) {
final SortedSet<BaseC<?>> s1 = new TreeSet<BaseC<?>>();
for (int i = 0; i < ITEMS; ++i) {
final BaseC<?> c = new BaseC<BaseC<?>>(i, ITEMS - i);
s1.add(c);
}
System.out.println(s1);
final SortedSet<SubC<?>> s2 = new TreeSet<SubC<?>>();
for (int i = 0; i < ITEMS; ++i) {
final SubC<?> c = new SubC<SubC<?>>(i, ITEMS - i);
s2.add(c);
}
System.out.println(s2);
final SortedSet<FinalC> s3 = new TreeSet<FinalC>();
for (int i = 0; i < ITEMS; ++i) {
final FinalC c = new FinalC(i, ITEMS - i);
s3.add(c);
}
System.out.println(s3);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment