Related
This question already has answers here:
Should I instantiate instance variables on declaration or in the constructor?
(15 answers)
Closed 9 years ago.
When I use Java based on my C++ knowledge, I love to initialize variable using the following way.
public class ME {
private int i;
public ME() {
this.i = 100;
}
}
After some time, I change the habit to
public class ME {
private int i = 100;
public ME() {
}
}
I came across others source code, some are using 1st convention, others are using 2nd convention.
May I know which convention do you all recommend, and why?
I find the second style (declaration + initialization in one go) superior. Reasons:
It makes it clear at a glance how the variable is initialized. Typically, when reading a program and coming across a variable, you'll first go to its declaration (often automatic in IDEs). With style 2, you see the default value right away. With style 1, you need to look at the constructor as well.
If you have more than one constructor, you don't have to repeat the initializations (and you cannot forget them).
Of course, if the initialization value is different in different constructors (or even calculated in the constructor), you must do it in the constructor.
I have the practice (habit) of almost always initializing in the contructor for two reasons, one in my opinion it adds to readablitiy (cleaner), and two there is more logic control in the constructor than in one line. Even if initially the instance variable doesn't require logic, having it in the constructor gives more flexibility to add logic in the future if needed.
As to the concern mentioned above about multiple constructors, that's easily solved by having one no-arg constructor that initializes all the instance variables that are initilized the same for all constructors and then each constructor calls this() at the first line. That solves your reduncancy issues.
I tend to use the second one to avoid a complicated constructor (or a useless one), also I don't really consider this as an initialization (even if it is an initialization), but more like giving a default value.
For example in your second snippet, you can remove the constructor and have a clearer code.
If you initialize in the top or in constructor it doesn't make much difference .But in some case initializing in constructor makes sense.
class String
{
char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
String()
{
this.arr=new char[0];
}
String(char[] arr)
{
this.arr=arr;
}
}
So depending on the situation sometime you will have to initialize in the top and sometimes in a constructor.
FYI other option's for initialization without using a constructor :
class Foo
{
int i;
static int k;
//instance initializer block
{
//run's every time a new object is created
i=20;
}
//static initializer block
static{
//run's only one time when the class is loaded
k=18;
}
}
The only problem I see with the first method is if you are planning to add more constructors. Then you will be repeating code and maintainability would suffer.
I recommend initializing variables in constructors. That's why they exist: to ensure your objects are constructed (initialized) properly.
Either way will work, and it's a matter of style, but I prefer constructors for member initialization.
Both the options can be correct depending on your situation.
A very simple example would be: If you have multiple constructors all of which initialize the variable the same way(int x=2 for each one of them). It makes sense to initialize the variable at declaration to avoid redundancy.
It also makes sense to consider final variables in such a situation. If you know what value a final variable will have at declaration, it makes sense to initialize it outside the constructors. However, if you want the users of your class to initialize the final variable through a constructor, delay the initialization until the constructor.
One thing, regardless of how you initialize the field, use of the final qualifier, if possible, will ensure the visibility of the field's value in a multi-threaded environment.
I think both are correct programming wise,
But i think your first option is more correct in an object oriented way, because in the constructor is when the object is created, and it is when the variable should initialized.
I think it is the "by the book" convention, but it is open for discussion.
Wikipedia
It can depend on what your are initialising, for example you cannot just use field initialisation if a checked exception is involved. For example, the following:
public class Foo {
FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException
}
Will cause a compile-time error unless you also include a constructor declaring that checked exception, or extend a superclass which does, e.g.:
public Foo() throws FileNotFoundException {}
I would say, it depends on the default. For example
public Bar
{
ArrayList<Foo> foos;
}
I would make a new ArrayList outside of the constructor, if I always assume foos can not be null. If Bar is a valid object, not caring if foos is null or not, I would put it in the constructor.
You might disagree and say that it's the constructors job to put the object in a valid state. However, if clearly all the constructors should do exactly the same thing(initialize foos), why duplicate that code?
Is there any difference between the following types of instantiation?
Whether I set the value directly where the variable is defined, or in the class constructor.
If not, what is best practice?
"In class":
class A {
boolean b = true;
public A(){
}
}
"In constructor":
class B {
boolean b;
public B(){
b = true;
}
}
The variable type is just for the example.
The only difference I see is, when the attribute is a complex type (a class) which constructor depends on values that are given to the constructor of the containing class:
class A {
B b;
public A(String s){
b = new B(s);
}
}
Actually they both are equivalent. From a readability point of view, however, the first one is more readable. Also, it's easy to see the default value when someone navigates to the variable declaration from an IDE (like ctrl + mouse-click in Eclipse).
Check out what the official tutorial has to say -
This works well when the initialization value is available and the
initialization can be put on one line. However, this form of
initialization has limitations because of its simplicity. If
initialization requires some logic (for example, error handling or a
for loop to fill a complex array), simple assignment is inadequate.
Instance variables can be initialized in constructors, where error
handling or other logic can be used. To provide the same capability
for class variables, the Java programming language includes static
initialization blocks.
So you can easily use the simple one-liner initialization technique when the process is simple. For complex initialization choices, constructors are the way to go.
If you assign the value to variable in the class, then while creating instance of the class, directly your desired value will get assigned to the variable.
If you assign values in the constructor, then your variables will be first assigned a default value and then the values from constructors will get assigned.
Read on initialization blocks, constructors and their order of execution
In case of best practice,
If passing all the values to the costructor is must while creating the object, then construction initialization must be used.
If there are some values which need to be default for every object, then you can assign outside constructors.
Use an initialization block. Initializing Fields
public class X {
// The following is the initializer block
{
}
public X() {
}
}
Instance variables are assigned default values in case you don't assign one! Bu default boolean instance variables are assigned value false.
public class HelloWorld {
boolean b;
public void printData() {
System.out.println("Defualt boolean value is " + b);
}
public static void main(String args[]) {
HelloWorld hw = new HelloWorld();
hw.printData();
}
}
and the output is Defualt boolean value is false.
Where are you assigning your variable is purely a design choice.
Both are almost same.
But an effective line from docs
. Instance variables can be initialized in constructors, where error handling or other logic can be used.
Instance field initializations are copied to the start of the constructor by the compiler, so the first two approaches generate the exact same code (or pretty darn close).
(Note however that the above is not quite true for static field initializations vs the static initializer method.)
It's mainly a question of which seems clearer and less likely to lead to confusion/errors down the road. And that depends on numerous factors, including personal style.
I'd recommend C:
class C {
private boolean b = true;
}
-> no (explicit) constructor -> less code -> easier to read
This question already has answers here:
Initialize class fields in constructor or at declaration?
(16 answers)
Closed 10 years ago.
What is the difference between the following two, and which is more preferable??
public class foo {
int i = 2;
}
public class foo {
int i;
foo() {
i = 2;
}
}
In your example, there is no difference in behavioural semantics. In Java, all instance field initializers (and instance blocks) are executed after superclass initialization, and before the body of the constructor; see JLS 12.5.
The difference lies in code readability and (in other examples) avoiding repetitious coding and fragility1. These need to be assessed on a case-by-case basis.
It is also worth noting that there are some cases where you have to initialize in the constructor; i.e. when the initialization depends on a constructor parameter.
1 - The repetitiousness and fragility issues are flip-sides of the same thing. If you have multiple constructors, the "initialize in constructor" approach tends to lead to repetition. And if you add extra fields, you might to add the initialization to all relevant constructors; i.e. fragility.
If you have two or more constructors and intialization value differs in each of them, then you should use constructor initialization as there is no way to do the same with member initialization...
however if you have just one constructor...you can use member initialization for better code clarity..
In particular this case there is no difference in these two variants. First variant is more preferable, because initializations of fields inside constructor, as usual, use external values from constructor arguments.
First of all I think the second example should look like this:
public class foo{
int i;
foo(){
i = 0;
}
}
Otherwise i is just a local variable in the C'tor scope.
Second, the first example shows initialization which is called before the class C'tor is invoked. this is good if you want this to happen no matter what C'tor is used.
It also enables you to declare i as readonly.
In your first example, i is an instance variable of class foo (better name would be Foo). It's initialised at class loading.
In your second example, i is also an instance varaible but in this case initialised in the foo() constructor.
There is no real difference here, and especially with primitives.
However, in a multi-threaded environment, if you do intend to initialise your ivars in your constructor, and those ivars are non-primitive, you need to avoid the risk of exposing a partially constructed object. The reason for this is that constructors aren't synchronised and can't have the synchronised keyword applied but then two threads can't be constructing the same object.
So, to avoid this, you should never expose this in your constructor. One way of doing so is to call non-final methods. Doing so, say calling an abstract method, allows some unknown code to do something with your unfinished object. Obviously, this can't be done if you initialise in your declaration.
p.s. I thought there was something on this in Effective Java but couldn't find anything.
I have the following variable in a class named Example:
private static int number;
If I wanted to assign the variable a number using an outside class, which would I do?
1) Make the setter method in Example static so I can access it like this:
Example.setNumber(3);
2) or Make the setter method non-static so I create an object of Example to set the number
Example e = new Example()
e.setNumber(3);
What are the differences between the two and which one is the better way?
It is recommendable to use a static method in this case.
Why? Well, if you make it a non-static method, that would lead to the following suprising effect:
Example e1 = new Example();
Example e2 = new Example();
e2.setNumber(3);
e1.setNumber(5);
System.out.println(e2.getNumber()); // surprise! prints 5,
So even though you called the method on e1, e2 is also affected. The corresponding static example is much less surprising:
Example e1 = new Example();
Example e2 = new Example();
Example.setNumber(5);
System.out.println(Example.getNumber()); // prints 5, no surprise...
First of all, you really shouldn't be setting static variables. It's prone to cause problems, and it's generally indicative of bad design. The only times static variables should be used are for thread-safe immutable objects and singletons.
That said, if you absolutely still want to set the value, make it a static method, ince you shouldn't need to instantiate the object in order to set a static value.
The first one would be the correct one. When you access a static method, you use the class name and not an object refrence
If it's a static variable, make the setter static. Having to create an instance just to modify something that belongs to the whole class is both verbose and wasteful.
Please don't use the second option. Creating an instance just for an assignment is a crime:P.
Use the first option or just make the number public, depending on your needs.
The setter of a static variable that do not depends on any instance variables/functions should be also static. So 1).
But beware of creating global variables!
There is no point to creating an instance of a class just to set a static variable on it. I would go with #1. (Although I try to avoid global variables, which is what the static variable is.)
Static member is the same for all instances of class. You can change is either using static or regular setter. But regular setter in this case may confuse user: the naming convention says that setter changes value of field that belongs to specific instance. Therefore you should use the first version: Example.setNumber(3).
Static variables are made static because they are not associated with any particular object.
Both approaches work, but the former is more sensible, because it does not require an arbitrary object to be created and used.
The consensus of other posters is for #1 static method.
I will argue that we can not answer the question with available information. If for example, the setNumber method is necessary to implement an interface then it should be #2 instance method. Tell us where the setNumber method will be used.
This question already has answers here:
Should I instantiate instance variables on declaration or in the constructor?
(15 answers)
Closed 9 years ago.
When I use Java based on my C++ knowledge, I love to initialize variable using the following way.
public class ME {
private int i;
public ME() {
this.i = 100;
}
}
After some time, I change the habit to
public class ME {
private int i = 100;
public ME() {
}
}
I came across others source code, some are using 1st convention, others are using 2nd convention.
May I know which convention do you all recommend, and why?
I find the second style (declaration + initialization in one go) superior. Reasons:
It makes it clear at a glance how the variable is initialized. Typically, when reading a program and coming across a variable, you'll first go to its declaration (often automatic in IDEs). With style 2, you see the default value right away. With style 1, you need to look at the constructor as well.
If you have more than one constructor, you don't have to repeat the initializations (and you cannot forget them).
Of course, if the initialization value is different in different constructors (or even calculated in the constructor), you must do it in the constructor.
I have the practice (habit) of almost always initializing in the contructor for two reasons, one in my opinion it adds to readablitiy (cleaner), and two there is more logic control in the constructor than in one line. Even if initially the instance variable doesn't require logic, having it in the constructor gives more flexibility to add logic in the future if needed.
As to the concern mentioned above about multiple constructors, that's easily solved by having one no-arg constructor that initializes all the instance variables that are initilized the same for all constructors and then each constructor calls this() at the first line. That solves your reduncancy issues.
I tend to use the second one to avoid a complicated constructor (or a useless one), also I don't really consider this as an initialization (even if it is an initialization), but more like giving a default value.
For example in your second snippet, you can remove the constructor and have a clearer code.
If you initialize in the top or in constructor it doesn't make much difference .But in some case initializing in constructor makes sense.
class String
{
char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
String()
{
this.arr=new char[0];
}
String(char[] arr)
{
this.arr=arr;
}
}
So depending on the situation sometime you will have to initialize in the top and sometimes in a constructor.
FYI other option's for initialization without using a constructor :
class Foo
{
int i;
static int k;
//instance initializer block
{
//run's every time a new object is created
i=20;
}
//static initializer block
static{
//run's only one time when the class is loaded
k=18;
}
}
The only problem I see with the first method is if you are planning to add more constructors. Then you will be repeating code and maintainability would suffer.
I recommend initializing variables in constructors. That's why they exist: to ensure your objects are constructed (initialized) properly.
Either way will work, and it's a matter of style, but I prefer constructors for member initialization.
Both the options can be correct depending on your situation.
A very simple example would be: If you have multiple constructors all of which initialize the variable the same way(int x=2 for each one of them). It makes sense to initialize the variable at declaration to avoid redundancy.
It also makes sense to consider final variables in such a situation. If you know what value a final variable will have at declaration, it makes sense to initialize it outside the constructors. However, if you want the users of your class to initialize the final variable through a constructor, delay the initialization until the constructor.
One thing, regardless of how you initialize the field, use of the final qualifier, if possible, will ensure the visibility of the field's value in a multi-threaded environment.
I think both are correct programming wise,
But i think your first option is more correct in an object oriented way, because in the constructor is when the object is created, and it is when the variable should initialized.
I think it is the "by the book" convention, but it is open for discussion.
Wikipedia
It can depend on what your are initialising, for example you cannot just use field initialisation if a checked exception is involved. For example, the following:
public class Foo {
FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException
}
Will cause a compile-time error unless you also include a constructor declaring that checked exception, or extend a superclass which does, e.g.:
public Foo() throws FileNotFoundException {}
I would say, it depends on the default. For example
public Bar
{
ArrayList<Foo> foos;
}
I would make a new ArrayList outside of the constructor, if I always assume foos can not be null. If Bar is a valid object, not caring if foos is null or not, I would put it in the constructor.
You might disagree and say that it's the constructors job to put the object in a valid state. However, if clearly all the constructors should do exactly the same thing(initialize foos), why duplicate that code?