alien01
alien01

Reputation: 1332

Passing generic types as generic method parameters in Java

First let me apologize for the terrible title, but I had no idea how to summarize this in a single sentence.

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
        }
    }
}

In the above code (the OutputStream is just an example) in class GarbageWriterExecutor class in the method first line causes compilation error, while the second one don't. I have two questions regarding this.

  1. Why stream.getInput() causes error, even though TypedStream.I is known to extend OutputStream?
  2. How can I solve this issue without the ugly casting?

Upvotes: 3

Views: 2038

Answers (4)

Rohit V Jain
Rohit V Jain

Reputation: 21

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.

Upvotes: 0

sp00m
sp00m

Reputation: 48817

Simply use:

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

I.e. parameterize your TypedStream parameter with I.

Upvotes: 1

Thomas
Thomas

Reputation: 88707

TypedStream stream will disable generic type checking and thus the compiler only knows that getInput() will return an object, hence the error.

Try writeTrash(TypedStream<I> stream) instead.

Maybe you event want to use writeTrash(TypedStream<? extends I> stream) in order to be able to pass any TypedStream which is parameterized for I or subclasses of I.

Yet another alternative would be

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

or

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

Upvotes: 3

Jonathan Drapeau
Jonathan Drapeau

Reputation: 2610

Because your method

public void writeTrash(TypedStream stream)

should also make sure TypedStream type is defined, like this :

 public void writeTrash(TypedStream<I> stream)

Edit : Thomas answer actually explain why

TypedStream stream will disable generic type checking and thus the compiler only knows that getInput() will return an object, hence the error.

Upvotes: 4

Related Questions