2

Randomly I came across this site: http://resources.mpi-inf.mpg.de/d5/teaching/ss05/is05/javadoc/java/io/FileNotFoundException.html

The class FileNotFoundException has three defined constructors:

    FileNotFoundException()
          Constructs a FileNotFoundException with null as its error detail message.

    FileNotFoundException(String s)
          Constructs a FileNotFoundException with the specified detail message.

    private FileNotFoundException(String path, String reason)
          Constructs a FileNotFoundException with a detail message consisting of the given pathname string followed by the given reason string.

But the last constructor is defined as private?

Again, here: http://www.docjar.com/html/api/java/io/FileNotFoundException.java.html we can see the full class definition. There is no other code, so the singleton pattern is obviously not used for that case, nor we can see, why it should be prevented to instantiate the class outside of the object, nor is it a factory method, static (utility class) method or an constants-only class.

I am C# dev so I might not be aware about some stuff that is going on here but I would still be interested why it is defined as private, for what it is used and if there is any example or an use case for that last constructor.

The comment mentions:

This private constructor is invoked only by native I/O methods.

Anybody explain this a bit further in detail?

eMi
  • 5,540
  • 10
  • 60
  • 109
  • 2
    Well, what's there to explain further? Apparently they decided that this particular constructor should not be used by Java code. The reason for that is hard to track down. – Kayaman Mar 27 '17 at 18:44

2 Answers2

4

Keep in mind: a lot of the libraries of the JVM are written in Java, like that exception. But when interacting with "the rest of the world"; sooner or later Java doesn't do any more - there is a need to talk C/C++ in order to make real system calls.

Meaning: certain operations related to file IO can't be completely implemented in Java. Thus native code comes in (compiled binaries). But of course, such a call can fail as well. But then one needs a mean to communicate that on the Java side - in other words: an exception needs to be thrown.

Given the comments that you are quoting this seems pretty straight forward: when certain IO related native operations fail; they will use that private constructor to create the exception that is then thrown at "you". And yes, native methods can call private methods!

Edit: but when looking at the implementation - there is really nothing specific about that constructor One could easily construct such an exception using the exact same message that this private ctor would create.

private FileNotFoundException(String path, String reason) {
  super(path + ((reason == null)
             ? ""
             : " (" + reason + ")"));
}

So, my personal guess: this could even be some "leftover". Something that had a certain meaning 15 years ago; but isn't of "real meaning" any more. Or even more simple, a convenience method allowing native code to either pass a null or a non-null reason string.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
3

The constructor in question is private so that no other class can use it to initialize an instance. It could, in principle, be used by the class itself -- that sort of thing is not unusual when one constructor is intended to be invoked by another, or by a factory method.

In this case, however, the documentation presents a different reason, which you in fact quoted:

This private constructor is invoked only by native I/O methods.

That seems clear enough to me, but I suppose your confusion may revolve around details of Java access control -- in particular, that it does not apply to native methods. Thus the native methods by which various I/O functionalities are implemented can instantiate FileNotFoundException via the private constructor, regardless of which class they belong to.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157