1

The below code is quoted from : http://examples.javacodegeeks.com/core-java/io/fileoutputstream/java-io-fileoutputstream-example/

Although the OutputStream is an abstract method, at the below code, OutputStream object is used for writing into the file.

Files.newOutputStream(filepath)) returns OutputStream. Then, the type of out is OutputStream, and out references OutputStream.

How can this be possible while OutputStream is an abstract class?

package com.javacodegeeks.core.io.outputstream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileOutputStreamExample {

    private static final String OUTPUT_FILE = "C:\\Users\\nikos\\Desktop\\TestFiles\\testFile.txt";
    public static void main(String[] args) {

        String content = "Hello Java Code Geeks";

        byte[] bytes = content.getBytes();

        Path filepath = Paths.get(OUTPUT_FILE);

        try ( OutputStream out = Files.newOutputStream(filepath)) {

            out.write(bytes);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
metis
  • 1,024
  • 2
  • 10
  • 26

1 Answers1

8

Just because the declared type is OutputStream, that doesn't mean the implementation doesn't create an instance of a concrete subclass of OutputStream. You see this all the time with interfaces. For example:

public List<String> getList() {
    return new ArrayList<String>();
}

Basically you need to distinguish between the API exposed (which uses the abstract class) and the implementation (which can choose to use any subclass it wants).

So Files.newOutputStream could be implemented as:

public static OutputStream newOutputStream(Path path)
    throws IOException {
  return new FileOutputStream(path.toFile());
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Knowing the implementation of newOutputStream as you show above, it is correct. Assuming that newOutputStream(path) returns OutputStream, rather than FileOutputStream, this example would be wrong. Right? – metis Jun 21 '15 at 19:41
  • 1
    @metis: No, it wouldn't - and I have no idea of whether that's *actually* the implementation or not. But the point is that code would compile and be fine. It's fine to return an instance of a subclass of the declared return type, just as I can use `OutputStream x = new FileOutputStream(...);`. What do you think would be "wrong" here? – Jon Skeet Jun 21 '15 at 19:43
  • Also, why should we need such a thing? Is there any reference title etc. which explain these? Because, in order to write such a code i MUST know that newOutputStream returns OutputStream. Why i would need such a thing? Is it related to polymorphism or other thing? – metis Jun 21 '15 at 19:45
  • 1
    @metis: Yes, this is precisely polymorphism. And I'm not sure what you mean by "in order to write such a code" - what code? You might want to read http://stackoverflow.com/questions/383947 though - I know that's about interfaces rather than abstract classes, but it's basically the same idea... you don't need to know the *exact* implementation used in order to use the returned value. – Jon Skeet Jun 21 '15 at 19:47