簡體   English   中英

Java泛型 - 參數化類與類型化方法

[英]Java generics - parameterized class vs. typed method

我想這是一個重復的問題,但在瀏覽了大量相關問題之后,我找不到匹配的問題......是的,蹩腳的借口;)

我目前正在為POI HSLF / XSLF實現開發一個通用接口。 使用泛型的原因是支持Iterable接口,其中用戶代碼不需要向下轉換為具體實現,即可以決定是否要使用實現類或公共接口。 當然,如果沒有泛型,返回類型縮小按預期工作。

我的目標是最小化類的用戶的參數聲明 - 請參閱main方法。 在內部,通用引用可能更復雜。

所以我想要這樣的東西:(為了簡單起見,我沒有使用Iterable接口,但是使用了不同的類型參數)

/ *更新:向類添加靜態並刪除空定義以實際具有運行示例* /

public class GenericsTest {
    static interface SlideShow {}
    static class HSLFSlideShow implements SlideShow {}

    static interface Notes<SS extends SlideShow> {}
    static class HSLFNotes implements Notes<HSLFSlideShow> {}

    static interface Slide<SS extends SlideShow> {
        <N extends Notes<SS>> N getNotes();
        <N extends Notes<SS>> void setNotes(N n);
    }

    // compile errors
    static class HSLFSlide implements Slide<HSLFSlideShow> {
        HSLFNotes notes = new HSLFNotes();

        @Override
        public HSLFNotes getNotes() { return notes; }
        @Override
        public void setNotes(HSLFNotes n) { notes = n; }
    }

    public static void main(String[] args) {
        HSLFSlide s = new HSLFSlide();
        HSLFNotes n = s.getNotes();
        s.setNotes(n);

        Slide<HSLFSlideShow> s2 = new HSLFSlide();
        Notes<HSLFSlideShow> n2 = s2.getNotes();
    }
}

我可以讓它與...合作......但這看起來有點笨拙:

    static interface Slide<SS extends SlideShow, N extends Notes<SS>> {
        N getNotes();
        void setNotes(N n);
    }

    static class HSLFSlide implements Slide<HSLFSlideShow,HSLFNotes> {
        HSLFNotes notes = new HSLFNotes();

        @Override
        public HSLFNotes getNotes() { return notes; }
        @Override
        public void setNotes(HSLFNotes n) { notes = n; }
    }

    public static void main(String[] args) {
        HSLFSlide s = new HSLFSlide();
        HSLFNotes n = s.getNotes();
        s.setNotes(n);

        Slide<HSLFSlideShow,HSLFNotes> s2 = new HSLFSlide();
        Notes<HSLFSlideShow> n2 = s2.getNotes();
    }

您如何最小化main方法中所需的類型參數(最小值是JDK6)?

據我所知,這里沒有理由使用通用方法。 用非泛型方法覆蓋泛型方法可能不會按照您的想法進行。 我在這里這里討論過這個問題 (另請參閱通用方法教程 。)

通用方法的類型由呼叫站點決定。 出於向后兼容性原因,允許將其覆蓋為非泛型。 一個人仍然可以出現並執行以下操作:

HSLFSlide slide = ...;
Slide<HSLFSlideShow> oops = slide;

// perfectly legal
// probably throws a ClassCastException somewhere
oops.<SomeOtherNotes>set(new SomeOtherNotes());

例如,通用方法允許我們定義一個返回它接受的相同類型的方法:

static <T> T pass(T t) { return t; }

String s = pass("abc");
Double d = pass(3.14d);

這是泛型方法有用的東西。

一個更典型的方法來做你想做的事情如下:

interface Slide<SS extends SlideShow> {
    Notes<SS> getNotes();
    void setNotes(Notes<SS> n);
}

class HSLFSlide implements Slide<HSLFSlideShow> {
    Notes<HSLFSlideShow> notes = new HSLFNotes();

    @Override
    public Notes<HSLFSlideShow> getNotes() { return notes; }
    @Override
    public void setNotes(Notes<HSLFSlideShow> n) { notes = n; }
}

如果要求參考類型的notes不能作為界面,則應再次查看您的設計。 例如, HSLFNotes實現可能具有應移至Notes界面的功能。

另一種方式如下:

interface Slide<N extends Notes<?>> {
    N getNotes();
    void setNotes(N n);
}

class HSLFSlide implements Slide<HSLFNotes> {
    HSLFNotes notes = new HSLFNotes();

    @Override
    public HSLFNotes getNotes() { return notes; }
    @Override
    public void setNotes(HSLFNotes n) { notes = n; }
}

還有問題的工作實例:

interface Slide<SS extends SlideShow, N extends Notes<SS>> {…}
class HSLFSlide implements Slide<HSLFSlideShow, HSLFNotes> {…}

這其實很好。

雖然這似乎是一個答案,請隨意添加另一種選擇:

public class GenericsTest {
    static interface SlideShow {}
    static class HSLFSlideShow implements SlideShow {}

    static interface Notes<SS extends SlideShow> {}
    static class HSLFNotes implements Notes<HSLFSlideShow> {}

    static interface Slide<SS extends SlideShow> {
        <N extends Notes<SS>> N getNotes();
        <N extends Notes<SS>> void setNotes(N n);
    }

    static class HSLFSlide implements Slide<HSLFSlideShow> {
        HSLFNotes notes = new HSLFNotes();

        @SuppressWarnings("unchecked")
        @Override
        public HSLFNotes getNotes() {
            return notes;
        }

        @Override
        public <N extends Notes<HSLFSlideShow>> void setNotes(N n) {
            notes = (HSLFNotes)n;
        }
    }

    public static void main(String[] args) {
        HSLFSlide s = new HSLFSlide();
        HSLFNotes n = s.getNotes();
        s.setNotes(n);

        Slide<HSLFSlideShow> s2 = new HSLFSlide();
        Notes<HSLFSlideShow> n2 = s2.getNotes();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM