将泛型类型作为Java中的泛型方法参数传递

时间:2013-10-02 14:10:00

标签: java generics inheritance

首先让我为可怕的头衔道歉,但我不知道如何用一句话来概括这一点。

public class GenericFun {
    public class TypedStream<I extends OutputStream> {
        I input;

        public I getInput() { return input; }
        public void setInput(I input) { this.input = input; }
    }

    public abstract class GarbageWriter<I extends OutputStream> {
        public void writeGarbage(I output) throws Exception {
            output.write("Garbage".getBytes());
        }
    }

    public class GarbageWriterExecutor<I extends OutputStream> extends GarbageWriter<I> {
        public void writeTrash(TypedStream stream) throws Exception{
            this.writeGarbage(stream.getInput());       // Error
            this.writeGarbage((I)stream.getInput());    // OK
        }
    }
}

在上面的代码(OutputStream只是一个例子)中,类GarbageWriterExecutor类中的方法第一行会导致编译错误,而第二行则不会。我有两个问题。

  1. 为什么stream.getInput()导致错误,即使已知TypedStream.I扩展OutputStream
  2. 如果没有丑陋的演员,我怎么能解决这个问题?

4 个答案:

答案 0 :(得分:4)

因为你的方法

public void writeTrash(TypedStream stream)

还应确保定义TypedStream类型,如下所示:

 public void writeTrash(TypedStream<I> stream)

编辑:托马斯回答实际上解释了原因

  

TypedStream流将禁用泛型类型检查,因此编译器只知道getInput()将返回一个对象,因此错误。

答案 1 :(得分:3)

TypedStream stream将禁用泛型类型检查,因此编译器只知道getInput()将返回一个对象,因此会出错。

请尝试writeTrash(TypedStream<I> stream)

也许您的活动想要使用writeTrash(TypedStream<? extends I> stream),以便能够传递为TypedStreamI的子类参数化的任何I

另一种选择是

public class GarbageWriterExecutor extends GarbageWriter<OutputStream> {
  public void writeTrash(TypedStream<?> stream) throws Exception{
    this.writeGarbage(stream.getInput());     
  }
}

public class GarbageWriterExecutor extends GarbageWriter<OutputStream> {
  public void writeTrash(TypedStream<? extends OutputStream> stream) throws Exception{
    this.writeGarbage(stream.getInput());     
  }
}

答案 2 :(得分:1)

只需使用:

public class GarbageWriterExecutor<I extends OutputStream> extends GarbageWriter<I> {
    public void writeTrash(TypedStream<I> stream) throws Exception {
        this.writeGarbage(stream.getInput());
    }
}

即。使用TypedStream参数化I参数。

答案 3 :(得分:0)

1.Resolve this by using this code.

 public void writeTrash(TypedStream<I> stream) throws Exception{
            this.writeGarbage(stream.getInput());       
            this.writeGarbage(stream.getInput());   
        }
2.  In Generic class class name is followed by a type parameter section. If you are not    doing this then you have to do casting.