In C++ its possible to have a default stream l开发者_JAVA技巧ike
class c
{
public:
c(istream fin =cin):fin(fin){}
}
Similary can I do this in java or is this wrong practice.Or is there a better way of doing this? I want to choose between reading from the console and reading from a file.
class c
{
c()
{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
}
c(int i)
{ FileReader f=new FileReader(path);
BufferedReader br=new BufferedReader(f);
}
}
"Yes they can".
However, I think most would advise doing as little as possible in the constructor. (And I suspect many would also argue that a constructor should not fail, excepting perhaps bad input). The constructor doesn't necessarily have to be the consumer. For instance, see how the Scanner class works. Also the Closeable interface is handy to help manage resources.
Happy coding.
You can certainly do that in Java. You might need to do something about possible IOExceptions being thrown. However, a better approach might be to define a constructor that takes a Reader
, so you could instantiate an instance using any data source:
class C {
C(Reader rdr) {
BufferedReader br = new BufferedReader(rdr);
}
}
(By the way, Java coding conventions are that class names begin with upper case letters.)
I also want to know if this is good software engineering practice since I didn't see bufferedreader objects being used within constructors as much when I tried to look it up
I would say that it is not good design to fundamentally join the "concerns" of parsing and constructing in an API. This is particularly important if the class is a general purpose one; i.e. one that is likely to be used / reused in different contexts.
However, provided that such a constructor is a really "convenience overload" for other more fundamental API methods / constructors that do the construction and parsing tasks, there is nothing wrong with it:
public Foo(Reader reader) {
this();
this.load(reader);
}
public Foo() {
...
}
public void load(Reader reader) {
...
}
I would use Reader
rather than BufferedReader
as the argument type. Some use-cases don't need the buffering of a BufferedReader
, and if your class is using the limited parsing capabilities of BufferedReader
, you shouldn't be exposing that implementation detail in your API methods ... all things being equal. (But pragmatics could dictate otherwise.)
If you need to use a BufferedReader internally, and you are worried about the (small) cost of an unnecessary filter in the output chain, do this:
public void load(Reader reader) {
BufferedReader br = (reader instanceof BufferedReader) ?
(BufferedReader) reader : new BufferedReader(reader);
}
Re your updated example:
Hard-wiring System.in
or a file name in the class is bad design. It makes the code too inflexible. A simple configuration change to read the data from somewhere else will entail a code change ... and probably a code search to find all of the other places where the paths, etc have been hard-wired.
精彩评论