开发者

Correct usage of "<T extends SuperClass>"

I am not familiar with "Generics". Is it a correct use of "<T extends SuperClass>" ? And do you agree that the codes after using generics are better?

Before using Generics
=================================================

public abstract class SuperSample {

    public void getSomething(boolean isProcessA) {
        doProcessX();
        if(isProcessA){
            doProcessY(new SubASample());
        }else{
            doProcessY(new SubBSample());
        }
    }

    protected abstract void doProcessX();

    protected void doProcessY(SubASample subASample) {
        // Nothing to do
    }

    protected void doProcessY(SubBSample subBSample) {
        // Nothing to do
    }

}

public cl开发者_开发问答ass SubASample extends SuperSample {

    @Override
    protected void doProcessX() {
        System.out.println("doProcessX in SubASample");
    }

    @Override
    protected void doProcessY(SubASample subASample) {
        System.out.println("doProcessY in SubASample");
    }

}

public class Sample {

    public static void main(String[] args) {
        SubASample subASample = new SubASample();
        subASample.getSomething(true);
    }

}

After using Generics
=================================================

public abstract class SuperSample {

    public void getSomething(boolean isProcessA) {
        doProcessX();
        if(isProcessA){
            doProcessY(new SubASample());
        }else{
            doProcessY(new SubBSample());
        }
    }

    protected abstract void doProcessX();

    protected abstract <T extends SuperSample> void doProcessY(T subSample);

}

public class SubASample extends SuperSample {

    @Override
    protected void doProcessX() {
        System.out.println("doProcessX in SubASample");
    }

    @Override
    protected <T extends SuperSample> void doProcessY(T subSample) {
        System.out.println("doProcessY in SubASample");
    }

}

public class Sample {

    public static void main(String[] args) {
        SubASample subASample = new SubASample();
        subASample.getSomething(true);
    }

}


If you want to do what I think you want to do, I don't think that this is the right way (*). If you want that every subclass needs to implement a method that processes it's own type, then you can use the CRTP trick:

abstract class Super<S extends Super<S>> {
   abstract void process(S s);
}

class SubA extends Super<SubA> {
   void process(SubA s){ /* do something */ }
}

class SubB extends Super<SubB> {
   void process(SubB s){ /* do something */ }
}

Note that this pattern enforces the generic signature of the subclasses, e.g. class SubA extends Super<SubB> wouldn't compile.

Java itself uses that trick in java.lang.Enum, by the way.

(*)If this is not the behavior you want to enforce, please clarify.


it's correct to use . It means that you restrict type T to be subclass of SuperSample. And for second answer, yes I think code with generecis is better because it keeps you from wrong casting of classes for example with containers (List ...). But in fact generics in Java are only syntax suger and so they are erased during runtime.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜