tags:

views:

394

answers:

12

I have to initialize file objects inside the constructor and for handling the exception, is it efficient using throws or should I go for try/catch?

A: 

I'd go with 'throws' if you care about what is initialized in the constructor, which I guess you do.

If you hide the exceptions, then that will probably cause problems later on.

jeff porter
Is that a proper coding standard using throws in constructor?
i2ijeya
No, it is not. Don't open files in a ctor. A ctor is for basic initializing of internal state. If you need to do file/network/database stuff, do it in an additional open()/init()/whatever() method.
EricSchaefer
@Eric, init methods are a code smell. If after every construction of an object you have to call init, then just put the init logic in the constructor. It's inevitable that the users of your objects will forget to call init and introduce a bug into their system.
Glen
So what? You need to call open() on a socket class, before you call send(). Thats called a protocol. Throw an exception if the object was not initialized as send() would do.
EricSchaefer
@Eric, Here's another protocol for you, if the file doesn't exist or can't be opened the constructor throws. pretty simple huh. and it has the advantage of not requiring the user of the object to call another method.
Glen
Good luck isolating such a class in a test harness...
EricSchaefer
+1  A: 

Generally it is a bad idea to do heavy lifting in constructors: in many languages, you'll be restricted anyhow in what can be done about exceptions during construction.

jldupont
Are you saying that because of restrictions of other languages you should never ever do it in Java? If this is your point, I do not agree.
Pascal Thivent
@Pascal: nothing is stopping you in **Java**, go ahead if you wish. But I guess since many other useful languages out there discourage such practice, you'll have one more "rule" to keep in mind when using other languages (C++ for example). If you are **ever** only going to tackle Java projects, feel free to disregard my input.
jldupont
Define "heavy lifting". I think this is like saying "don't do too much" ... without saying how much is too much.
Stephen C
@jldupont, Throwing from a constructor in C++ is encouraged, you just have to use the RAII idiom correctly. besides, when writing Java (as this question is tagged) you should write idiomatic Java and not worry about how other languages do things.
Glen
@jldupont You comment is more valid that your answer (which was my point). But I'm with @Glen here.
Pascal Thivent
Guys - as I said, do what you want of course: as far as I am concerned, Java is just one language in my toolbox and I prefer not to do heavy lifting (stuff that is complicated enough to mandate to use exceptions to manage the control flow). I am done arguing on this question.
jldupont
A: 

Of course, it's actually used a lot in Java. For example,

public FileInputStream(String name)
                throws FileNotFoundException
ZZ Coder
+7  A: 

Of course you can and throwing an exception is actually what I would do (instead of swallowing it in the constructor). You want to let the caller know that something unexpected happened, you don't want to return a non properly initialized instance. That said, it may be a sign that you are doing too much things in the constructor.

Pascal Thivent
Why the downvote by the way? Care to explain?
Pascal Thivent
+1 to compensate that. Downvoting shouldn't be able without commenting.
BalusC
@BalusC That would be nice indeed.
Pascal Thivent
+11  A: 

It's okay to throw an exception in the constructor. I know some of the Java library classes do so (URI for just one example). I think it's better to throw an exception than to return an object in an unknown or invalid state.

Bill the Lizard
The `URL` class isn't a good example for anything other than bad code. For example, its `equals` method will return different values depending on whether you are connected to the internet or not, etc. (Just a side not, your answer is great)
abyx
@abyx: Now that you mention it, I totally agree about URL. I changed my answer to use URI as an example instead. Thanks.
Bill the Lizard
One thing to note with URI/URL, though is that the exception is thrown if you give it bad input, not because something happens under the covers (like not being able to open a file, or do it's DNS lookup, whatever)
Chad Okere
@Chad: There's not much difference. An exception is thrown because a valid object can't be created.
Bill the Lizard
+1  A: 

You are supposed to take the object to a safe state in the constructor, but let's imagine you want to open a file(for reading) that doesn't exists, throwing the exception is the only way. So it depends on the logic you implement

Svetlozar Angelov
Well, how about not opening a file in a ctor? When will people learn...
EricSchaefer
why not open a file in a constructor, especially if your object is meant to operate on that file?
Glen
Yeah, tats the point glen, My object will works on the file which i am gonna open it in the constructor
i2ijeya
@i2ijeya, if your object cannot function without the file, then throw an exception from the constructor. it's a legal and well understood pattern in java. See the FileInputStream example others have posted.
Glen
http://objectmentor.com/resources/articles/TestableJava.pdf
EricSchaefer
Thanks glen.. I am gonna do that only.
i2ijeya
^TestableJava.pdf
EricSchaefer
+2  A: 

To me, that's not a question of efficiency.

If you can react on the exceptional state and still create a valid or at least useable object, then handle it within the constructor.

Otherwise - in case the object is not usable - throw the exception back at the caller. In that case, he won't get an object and can't continue with an unusable/inconsistant instance which might produce errors in some other corners of the application.

Andreas_D
@Downvoter - please review SO FAQ and leave a comment
Andreas_D
+2  A: 

I suggest try/catch, and throw usefull errors from your catches. This will give users a better sense of what is going wrong with your application. For example you should check for file existence, and properly formated conditions.

Jay
A: 

In general it is a good idea to have only simple logic in your constructor (for example setting private fields with arguments values). And set up your objects with other special "assemblers", "preparers" or "factories". The same is about get/set methods- they should be as simple as possible.

Sure it is possible to throw an exception from constuctor. But this is not a good practice.

Andrew Dashin
The constructor should leave the object in a usable and consistent state, no matter what it has to do. If it can't, for whatever reason, it needs to signal that. Returning some sort of error code is asking for bugs, and the other choice is to throw an exception.
David Thornley
So what? I mean that in most cases constructor shouldn't try to perform any action that could fail.
Andrew Dashin
+1  A: 

I think throwing exception in contructor is an elegant way to indicate error condition inside a constructor.Otherwise you have to create another function which initializes the resources and call that function after the object is constructed.

NightCoder
+3  A: 

You sure can (for example, FileOutputStream does).

Throwing an exception from the constructor should be done wisely - make sure you clean up after yourself cleanly. Throwing exceptions in a constructor is sometimes done in order to make sure RAII is held.

abyx
+6  A: 

Consider a constructor, or for that matter any method, to have a contract. The contract for a constructor is very simple - you give me (zero, one or more) parameters and I'll give you back a constructed object. Good practice would suggest that this object should have its internal data structures properly initialised and invariants intact, although there's nothing in the language to enforce this per se.

If, for some reason the constructor cannot hold to this contract, then it should throw an exception. That might be because the parameters passed (if any) were not acceptable (pre-condition failure) or some external problems (file-system full, heap exhaustion, network outage etc.) prevented it.

jhumble