Java 泛型 - 参数化类与类型化方法

标签 java generics inheritance apache-poi parameterized-types

我想这是一个重复的问题,但在浏览了大量相关问题后,我找不到匹配的问题......是的,蹩脚的借口;)

我目前正在为 POIs HSLF/XSLF 开发一个通用接口(interface)实现。 使用泛型的原因是支持 Iterable接口(interface),用户代码无需向下转换为具体实现,即可以决定是使用实现类还是公共(public)接口(interface)。 当然,如果没有泛型,返回类型缩小会按预期工作。

我的目标是为类的用户最小化参数声明 - 请参阅 main 方法。在内部,通用引用可能更复杂。

所以我想要这样的东西: (为了简单起见,我没有使用 Iterable 接口(interface),而是使用了不同类型的参数)

/* 更新:向类中添加了静态并删除了空定义以实际拥有一个运行示例 */

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)?

最佳答案

据我所知,没有理由在这里使用泛型方法。用非泛型方法覆盖泛型方法可能并没有按照您认为的那样进行。我已经讨论过这个 herehere . (另请参阅 generic methods tutorial。)

泛型方法的类型由调用点决定。出于向后兼容的原因,允许将其覆盖为非泛型。仍然可以出现并执行以下操作:

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的引用类型不能是接口(interface),你应该再看看你的设计。例如,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> {…}

这实际上很好。

关于Java 泛型 - 参数化类与类型化方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29440337/

相关文章:

java - 单元素枚举类型 Singleton 真的是一个被广泛采用的好主意吗?

java - EJB 和 Flash 之间可以通信吗?

r - 为新类定义 S3 "Math"组泛型时出现意外的 log2 错误

java - 子类不继承所有方法

java - 为什么我无法访问 protected 字段?

java - CompletableFuture 立即失败

java - 对返回 HashMap 的方法使用泛型键

java - 如何声明 Map 的通用 Map

java - 在 Java 中重写常量

javascript - 如何使用ES6类扩展Function?