Are instance initializers considered bad style? - java

I personally quite like instance initializers - I use them to assign default values to things such as collections so when writing constructors I don't have to remember to assign them the same default values each time. It seems quite elegant to me - avoids annoying NPE's popping up and avoids duplicate code. A private method doesn't seem as nice because a) it can't assign values to final fields, b) it could be run elsewhere in code and c) the method still needs to be explicitly called at the start of each constructor.
However, the flip side with others I have spoken to is that they're confusing, some people reading the code might not understand what they do or when they're called and thus they could cause more problems than they solve.
Are proper use of these initializers something to be encouraged or avoided? Or is it an "each to their own" case?

It depends, for instance on the level of knowledge about Java readers of your code can be expected to have, and whether the alternatives are practical.
Alternatives are:
inline into every constructor. If there are several constructors, this violates DRY.
have all constructor delegate to the same constructor, and put the code in that one. If the constructors are non-trivial, and take different arguments, this might require to write a new constructor that receives the values of all fields in its arguments. If there are many fields, this can get rather lengthy (and hard to read, since it is not obvious which value is being assigned to which field)
have all constructors invoke an init method. Can't assign final fields that way. Should probably prevent the method from being overridden. Might want to prevent it from being called several times.
Since initializers are uncommon, you should only prefer them when there is a clear advantage to using them. My most recent use of one was:
private final Collator collator = Collator.getInstance();
{
collator.setStrength(Collator.SECONDARY);
}
in a class with several constructors with rather different argument lists and half a dozen other fields.

I don't really use them but one case I can see them useful is when you have multiple constructors, not calling themselves (this(..)), that need some common initialization logic shared, and no need to create a specific private method for that.
Oh and the only place I use instance initializers are for quickly initialize in one-line Maps for instance, eg:
Map<String,String> m = new HashMap<String,String>(){{
put("a","b");
put("c","b");
put("d","b");
}};
Could be useful to initialize a map in let's say an interface
interface A {
Map<String,String> PROPS = Collections.unmodifiableMap(new HashMap<String,String>(){{
put("a","b");
put("c","b");
put("d","b");
}});
}
Still doing so you end up with a annonymous subclass of HashMap...

It is better to overload your constructor and have as many constructor variations as you like. The best example is Java's Arraylist. It has two constructors. One that takes a integer as an argument and other being a default constructor. If you take a look at the default constructor, it infact calls the Single argument constructor with a constant value 10.
List<Object> x = new ArrayList<Object>(); //Creates with default capacity 10
List<Object> y = new ArrayList<Object>(40); //Creates with the specified capacity 40

I would stay they are preferred. But based on the other responses it appears it might be more "to each his own". I like them because it keeps the related information together. Rather than declaring a value and setting it in the constructor, you can do it all in one place.

You can use a constructor with parameters and this constructor calls the private setters. And than implement a default constructor who calls that contructor with default values. If you want assign default values to properties, do it in the declaration.
The instance and static initializers are good to init complex datastructures like matrices or cubes.
By the way, a final property is mostly called a constant.

Related

Why shouldn't all function arguments be declared final?

Ok, so I understand why we should declare an argument to be final from this question, but I don't understand why we shouldn't...
Since Java always uses pass by value, this means that we can't return a new value through the given argument, we can only overwrite it, and make the argument useless therefore, because we don't use the passed value...
Is the only benefit of non-final method arguments in Java the fact that you don't have to make a local variable of the arguments' type?
P.S. This question was triggered by PMD's rule of MethodArgumentCouldBeFinal
I can think of only 2 reasons not to make a parameter final:
to save the use of a local variable if you need to overwrite the parameter's value in some edge cases (for instance to put a default if the param is null etc.).
However, I wouldn't consider that a good practice in general.
to save 6 characters per parameter, which improves readability.
Reason 2 is what leads me not to write it most of the time. If you assume that people follow the practice of never assigning a new value to a parameter, you can consider all parameters as implicitly final. Of course, the compiler won't prevent you from assigning a parameter, but I can live with that, given the gain in readability.
It prevents you from making unintentional error in your code. Rule of thumb here is to make each field and each function argument you know you shouldn't change (I mean reference, you still can change value) in your code as final.
So basically its a mean to prevent programmer from shooting their foot. Nothing more.
Whether you've to declare a local variable final or not (method parameter comes under this), is more of the requirement than a convention. You'll not get a certain answer saying you should always use final or you should never use final. Because that is really a personal preference.
I personally mark the parameters or local variables final when I really don't want their values to be changed, and it even shows my intention to other developers not to overwrite the values. But I don't do it for every parameters. Also for some, using final seems to be noise, as that really increases the code base.
Rule of thumb: Don't use it.
Final cannot stop you changing objects, only its reference, and this is because objects in java are, usually, not inmutable.
Take a look to this code:
class Example{
// think about this class as a simple wrapper, a facade or an adapter
SomeClass inner = new SomeClass();
setInnet(Someclass inner){
this.inner = inner;
}
// delegate methods.....
}
Now, in a method:
private void (final Example examp){
....
examp will be always the same object, but inner can vary... And inner is the important object here, the one which makes everything!
This may be an extreme example, and you may think that inner could be final but, if it's a utillery class, maybe it shouldn't. Also it's easy to find a more common example:
public void (final Map map){;
....
//funny things
....
//and then, in a line, someone does:
map.clear()
// no we have the same reference... but the object has change...
....
So, my point against final in arguments is that it's not guaranteed that all the code inside a final class is inmutable and so the final word can end lying you and mascarading a bug...
By putting final in params you can only show wishes, not facts, and for that you should use comments, not code. Moreover: it's a standar (de facto) in java that all arguments are only input arguments (99% of the code). Thus, final word in params is NOISE because it exists and means nothing.
And I don't like noise. So I try to avoid it.
I only use final word to mark the inner variables that will be used in an anonymous inner class (you can avoid marking it if they are effectively final, but it's cleaner and more readable).
UPDATED
final means 'assigned once' which in applied to method arguments means nothing in a program's logic nor in its design.
You can assign the arguments to a new object inside a method and outside there will not be any change.
The only difference putting final in arguments will be that you will not be able to assign that entities to another objects. Assigning arguments is something which may be ugly and something to avoid but its only a style problem and, at that point, the style problem should be the assignation itself and not the ausence of 'final' word.
I think that final is useless in arguments (and so, noise), but if someone is able to find a use of it I'll be happy to learn it. What can I achieve putting 'final' that cannot achieve without putting it?

Initializing 'final' Fields of Varying Types in Subclasses

My problem is almost exactly the same as the problem posted here: Abstract class with final uninitialized field and I like the solution. However, my problem is a bit more complicated in that the abstract class has multiple final fields of varying types. For example, I have four int, two int[], and two double. What would be the best way to force the subclasses to initialize these variables?
Options I've considered:
Convert all fields to Strings and pass with a Map
Have a really long superclass constructor
Create a helper class that would act as a wrapper and encapsulate all the values, then pass an instance of this class to the base class
The first option is not very elegant, and seems a bit complicated, especially with arrays. The second option is very tedious, and the third option just seems like I'm overdoing it.
Is there a "correct" way of doing this? Or if not, which of the three options posed would be the most elegant?
I would go with the second, "Have a really long superclass constructor." If we follow the approach detailed in the question you referenced, the superclass constructor is protected and not meant to be called by anything external to the class hierarchy or package. My feeling always is, once something is not exposed beyond that boundary - i.e., is not part of the "API" as it were - then it doesn't matter what it looks like. Let it have eight different parameters of varying types, or even more. Yes, it's visible from within the package, but it's clear from the original solution that that constructor is not meant to be called by anything other than the subclasses. That's another motivation for non-public visibility.
Of course, your instincts for doing something cleaner are correct when it comes to public stuff. The fact that you asked this question at all shows you have the right instincts.
Here's another alternative, assuming you have control of all the classes involved: abstract out the fields in the superclass and declare them in the subclasses, sort of like this...
abstract class SuperClass {
abstract int[] getFooArray(); // not public!
abstract int getBar();
}
and then just define the field in each of those subclasses, overriding the methods to return them.
Yes, it will involve some code duplication, but it could very well be cleaner in the end than an unreadably long constructor, and the code you're duplicating isn't very much -- a field, a one-line method to return that field.
However, my problem is a bit more complicated in that the abstract
class has multiple final fields of varying types.
I'm not sure I understand the added complexity in your scenario, but I'm interpreting your issue as : I don't want to have a ton of arguments on my abstract constructor. One possible approach is to have a Builder for the abstract class that is used by the concrete sub classes. The builder is then 'passed up' to the abstract constructor for setting the final fields.
When I have a need for an immutable object (all members are final) that takes many different parameters in the constructor I usually use a Builder pattern.
In this case you can make the builders subclass each other and in this way you will still maintain the ability to extend.
For an example you can see the Guava API for ImmutableCollection Builder.
Or if you don't require immutability, here is an example of CacheBuilder also taken from the same library:
Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
As you can see the use of a builder replaces the need to pass in 6 parameters in the constructor and makes for more readable/usable code.
If you still don't want to use builders I would go with option (3) as that will prevent some of the hassle of maintaining a very long constructor

No-Parameter Constructor v/s Constructor with params

which one of below is better or to be prefered
new Object();
Object.setValue1("1");
Object.setValue2("2");
Object.setValue3("3");
or
new Object("1","2","3");
(I assume you're talking about the design of your own classes, rather than how to use other already-designed classes.)
Neither is always "better," it depends on the nature of the object and (to an extent) on your preferred style.
If an object cannot have a meaningful state without some external information, then requiring that information in the constructor makes sense, because then you can't create instances with an invalid state.
However, having constructors that require as little information as possible is useful in terms of making the class easy to use in a variety of situations. If the class is such that a zero-arguments constructor is feasible and doesn't complicate the class, it's great in terms of supporting various use-cases, including cases where the instance is being built as part of parsing some other structure (JSON, XML, etc.).
There is also a third option that builds on the use of fluent interfaces
MyObject obj = new MyObject().setValue1("1").setValue("2").setValue("3");
I personally like this approach but if the number of parameters is short and known at the time of construction AND the varying possible combinations of parameters is short then I would take the route of parameters on the constructor. I think most would agree that 12 constructor overloads are an eye sore.
Depends on whether you know the values at the time of object construction.
If Yes, then use the constructor version if not then you will have to use the other version.
Ofcourse,Initialization through the Constructor version is faster because it involves just one function call over 3 set function calls and also it is more logical way.
Its always better performance to call in constructor If you know values already.
Then there is my preferred alternative. Thing is the name of some interface. It creates an anonymous class.
Thing createThing ( final int val1 , final int val2 , final int val3 )
{
return new Thing ( )
{
// can use val1, val2, val3
} ;
}
It all depends on the application.
Calling Parameterized constructor will be a good idea if at Compile time you know what values to be given to your variables, rather than calling Setters. Because you are calling 3 setter methods and in parameterized constructor, you are just passing to the cnostructor it self.
But if at compile time you don't know what values to be given then how can you call paramterized constructor.
But for initialization it will be better to call parameterized constructor.
There is a semantic difference. If (1) you are instantiating an object with an initial state. In (2) you are changing the state of an existing instance (3 times). It's a small difference but may become very important in more complex systems (especially if you rely on various JavaBean conventions). But still, neither one is wrong or better.

what's the difference between those two ways to initialize fields in Java?

Assign value to field at the same time with field declaration
Assign value to field in the constructor?
What's the difference between those two ways to initialize fields in Java?
Not much! The main difference is that if you assign it at the point of declaration, it will apply to all constructors. That is, there's no way you can forget to add the initialization to any future constructors.
Have a look at the official Initializing Fields trail.
May be worth noting that if you initialize the fields at the declaration, it happens before the constructor starts executing.
As a rule of thumb, I usually initialize the "dead simple" fields at the declaration (when there is no doubt what the initial value should be). This "cleans up" For instance
class SomeClass {
List<Integer> currentNumbers = new ArrayList<Integer>();
int counter = 0;
// ...
}
while as if there is the slightest chance that I may want different behaviors in different constructors, I leave it to the constructor.
In both cases, the value will only be assigned after the superclass constructor has executed.
For the first option, you have to be able to determine the value without reference to any constructor parameters.
For the second option, you'll need to assign the value in every constructor overload.
Basically I tend to favour the second option when the value depends on constructor parameters (usually that's all I would want it to depend on) and the first option when the value will be the same for any newly initialized instance. I tend not to mix and match for a single field, using an initializer with the declaration and also assigning it in some constructor overloads, but even that can be useful occasionally. (Imagine a collection which has a size of 0 for most constructors, but has one constructor which takes an initial set of values.)
While you can refer to other instance members in variable declarations, I prefer not to - calling instance methods when your object is only partially initialized is brittle, and referring to other variables relies on the variable ordering, which feels ugly to me.
(1) is a syntax sugar for (2) (with the exception of static fields)
It does exactly the same, just at different times in the object instantiation life-cycle. Have a look here for more information.
In the first case the field will be created when the class is initialised and assigned directly the value you hace declared for it, while in the second case the field will be created and assigned a default value (null if it's an object, 0 if it's an int, etc.) and then assigned the correct value when the constructor is executed. Of course practically there's usually not much difference for you since the result in both cases is the same: when you create an instance of this class after the constructor returns the field is initialised correctly. I guess the first approach would be more usefull if you have more than one constructors and a field which should have the same value regardless of which constructor has been called.

How much code should one put in a constructor?

I was thinking how much code one should put in constructors in Java? I mean, very often you make helper methods, which you invoke in a constructor, but sometimes there are some longer initialization things, for example for a program, which reads from a file, or user interfaces, or other programs, in which you don't initialize only the instance variables, in which the constructor may get longer (if you don't use helper methods). I have something in mind that the constructors should generally be short and concise, shouldn't they? Are there exceptions to this?
If you go by the SOLID principles, each class should have one reason to change (i.e. do one thing). Therefore a constructor would normally not be reading a file, but you would have a separate class that builds the objects from the file.
Take a look at this SO question. Even though the other one is for C++, the concepts are still very similar.
As little as is needed to complete the initialization of the object.
If you can talk about a portion (5 or so lines is my guideline) of your constructor as a chunk of logic or a specific process, it's probably best to split it into a separate method for clarity and organizational purposes.
But to each his own.
My customary practice is that if all the constructor has to do is set some fields on an object, it can be arbitrarily long. If it gets too long, it means that the class design is broken anyway, or data need to be packaged in some more complex structures.
If, on the other hand, the input data need some more complex processing before initializing the class fields, I tend to give the constructor the processed data and move the processing to a static factory method.
Constructors should be just long enough, but no longer =)
If you are defining multiple overloaded constructors, don't duplicate code; instead, consolidate functionality into one of them for improved clarity and ease of maintenance.
As Knuth said, "Premature optimization is the root of all evil."
How much should you put in the consructor? Everything you need to. This is the "eager" approach. When--and only when--performance becomes an issue do you consider optimizing it (to the "lazy" or "over-eager" approaches).
Constructors should create the most minimal, generic instance of your object. How generic? Choose the test cases that every instance or object that inherits from the class must pass to be valid - even if "valid" only means fails gracefully (programatically generated exception).
Wikipedia has a good description :
http://en.wikipedia.org/wiki/Constructor_(computer_science)
A Valid object is the goal of the constructor, valid not necessarily useful - that can be done in an initialization method.
Your class may need to be initialized to a certain state, before any useful work can be done with it.
Consider this.
public class CustomerRecord
{
private Date dateOfBirth;
public CustomerRecord()
{
dateOfBirth = new Date();
}
public int getYearOfBirth()
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateOfBirth);
return calendar.get(Calendar.YEAR);
}
}
Now if you don't initialize the dateOfBirth member varialble, any subsequent invocation of getYearOfBirth(), will result in a NullPointerException.
So the bare minimum initialization which may involve
Assigning of values.
Invoking helper functions.
to ensure that the class behaves correctly when it's members are invoked later on, is all that needs to be done.
Constructor is like an Application Setup Wizard where you do only configuration. If the Instance is ready to take any (possible) Action on itself then Constructor doing well.

Categories

Resources