Why we instantiate some object inside constructor and some outside. What are the advantage/ disadvantages of doing this.
public class HomePage_Util {
private Common_Functions cfObj = new Common_Functions();
HomePage_OR home_ORobj;
Logging logObj = new Logger();
public static String scptName;
public ArrayList<String> homeScriptMsgList = new ArrayList<String>();
public HomePage_Util(WebDriver driver) {
home_ORobj = new HomePage_OR();
PageFactory.initElements(driver, home_ORobj);
}
Objects are initialized in constructors only when they are needed to initialize other objects in a sequence. Like in your example first of all the object i.e. home_ORobj = new HomePage_OR(); will be created as this object is needed to initialize the PageFactory elements in next step.
So if home_ORobj = new HomePage_OR(); is not needed to initialize the PageFactory elements then you could write it out of the constructor i.e. globally.
Code reuse is the main advantage of initializing elements in a constructor. Also initializing few things makes sense only when the object is created or constructor is called.
Constructor is basically for creating a new object of a class. When you create an object, a copy of all variable for that object is created and assigned default value.
The purpose of initiating some variables in constructor is to assigned the value at the time of creation of an object. So that you don't have to assigned value implicitly.
My guess is the writer of such code wasn't sure if home_ORobj would be initialized before the call to initElements() but the ones outside are initialized first so it doesn't matter.
Though if they depend on each other (i.e. use another in the parameters to the constructor) it's good to put them in the constructor as code formatters may re-order the list of elements breaking the the code.
Some objects requires few fields to be initialised in order to correctly construct that object before it being used. Constructor is called when the object is getting created, hence it is initialised in constructor.
You can have overloaded constructor with different initialistion for different scenarios.
You can always have a method called initializeValues and call it after you create an object rather than putting it in constructor.
Putting it in constructors will ensure that it is always called when you create an object.
Super class constructor is always called before the derived class constructor, so it makes sense.
One advantage is to avoid a static block to initialize static members.
AFAIK It's not exactly the same in the lifecycle of an object : constructor is executed after the firsts initializations.
An instance field that is initiated outside a constructor is always going to be that way initially when a new object is created - for every instance. The ones initiated in a constructor may have some special meaning for the new instance such as the WebDriver in your example seems to have so it cannot be initiated elsewhere. A constructor that requires an instance of certain type to be passed as an argument does enforce design since it cannot be passed anything else and cannot be constructed without it.
A class may contain multiple constructors that may behave differently and instantiate different fields and leave others untouched (like when there are multiple purposes for a class, which actually may indicate bad design).
Additionally, if a class does not have a default constructor => upon deserialization no constructor's get called.
Related
Assume I have the following class:
public abstract class Test {
private List<String> strings = new ArrayList<>();
// to be called concurrently
public int getStringsSize() {
return strings.size();
}
}
Is there a chance that getStringsSize() will throw NPE for some subclass of Test? Or what else can go wrong? As far as I understand there're no Java Memory Model guarantees about such case.
The point is: when a subclass object gets instantiated, the super constructor and super field init statements will be executed before any subclass code is executed. See here or there for more information. In other words: before a client that creates a subclass via new gets access to the newly created object, it is guaranteed that those init statements were executed.
And as we are talking about a single private field that only lives in the super class, there is no chance for that method call to produce an NPE
Unless you have some other method that resets the field to null. Which you can avoid by using the final keyword for that field (which is good practice anyway: make it your default to put final on fields).
Finally; for completeness: it is possible to write super/subclass code that fails when doing new on the subclass because of "something not initialized yet" - like when your super class constructor calls a method that is overridden in the subclass. But that is like: bad practice (as it can lead to such bizarre errors). So don't even think about doing that.
No. As long as the strings field is not reassigned (which can never be done by a subclass since it is private), then it will never be accessed in a null state, no matter how many threads try to access it. And as such, strings.size() can never throw a NullPointerException.
getStringSize() would only throw NPE if you set strings to null manually, EG in a setStrings() method. getStringSize() should also be set final.
The initializer runs at instantiation time, that is after the super(...) constructor, but before the first instruction of this(...) constructor.
According to the definitions of constructors they don't have any return types,but while creating object we often do A a = new A(); which is responsible for creating the object a.
A a=new A();
Can anyone help me understanding the issue,what is actually happening in the case of constructors while creation of Object.
Constructors don't have return types, correct. But the expression new A() does have a result: A reference to the newly-created object.
Here's what happens with new A():
An object is created
It's given the type A
The relevant A constructor is called with this referring to that new object
Once initialization is done, the expression completes
The result of the expression is the reference to the new object
This process is described in this tutorial on the Oracle Java site.
In many ways, it would be more accurate to call constructors initializers: The construction happens because of the new operator, not the constructor.
The fact that constructors don't actually do the construction is made particularly clear when an object is processed by multiple constructors, as is very common. Consider:
List<String> m = new LinkedList<String>();
One object is created (ignoring any fields the list may need to initialize), but five different constructors get called to initialize that one object, because LinkedList<E> subclasses java.util.AbstractSequentialList<E> which subclasses java.util.AbstractList<E> which subclasses java.util.AbstractCollection<E> which subclasses java.lang.Object, and each of those classes has to get its chance to initialize its part of the object that was created. So in order:
JVM creates the object
Object() is called to initialize Object stuff
AbstractCollection() is called to initialize its stuff
Then AbstractList()
Then AbstractSequentialList()
Then LinkedList()
And then finally the resulting (one) object's reference becomes the result of the new expression
One object, but five constructors required to initialize it. :-)
Constructors need not to return anything. They just constructs the current instance. That's all their job, part of object creation.
Creating objects:
A a = new A();
Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Constructor declarations look like method declarations—except
that they use the name of the class and have no return type - from
the java constructor docs
To understand the constructor, it is similarly important to understand how it differs from a method.
Constructors have one purpose in life: to initialize the new object and it's fields. Nothing more. The new keyword handles the creation of memory space.
You shouldn't consider new A() to be a call to the constructor, because there are more things that happen, than just the constructor running. The major steps, when you run new A() are these.
A chunk of memory is set aside - just enough for storing an object of class A.
The constructor is run.
A reference to the chunk of memory that was set aside is returned.
So the constructor itself isn't actually returning anything - and it's an error to have return this; or anything similar inside the constructor.
Return statement inside a constructor doesn't logically makes sense because the purpose of the constructor is to perform initialization. The object has not been created yet, the actual construction of the object happens in JVM.
I believe I understand what constructors are now, but to me it seems they are just used for passing info to methods in another class. So why not just call a method and supply a parameter instead? Have I got this wrong?
Constructors are used to create objects and are not ordinary methods. Whenever you use new to create an object, you actually call a constructor. For example:
new MyClass(); //here MyClass() is a constructor with no params
Note:
Constructor declarations look like method declarations—except that
they use the name of the class and have no return type
If I understand it right:
Constructors are always called, so these attributes MUST BE passed. If you pass this info through methods they don't have to be passed, so they could be missing.
Constructors are used to initialize new instance of an object, whenever you pass parameters or not.
Having parameters in a constructor is just a way to make it easy to set some initial attributes during the object initialization, which the object will most probably need in order to work as expected.
However, if those attributes weren't needed to be initialized for the correct operation of the instance object, it would make more sense not to pass them to the constructor, but just having some setters to pass them at any other time you need.
As per standard book constructor is a special type of function which is used to initialize objects.As constructor is defined as a function and inside class function can have only two type either static or non static.My doubt is what constructor is ?
1.)As constructor is called without object so it must be static
Test test =new Test();//Test() is being called without object
so must be static
My doubt is if constructor is static method then how can we frequently used this inside
constructor
Test(){
System.out.println(this);
}
Does the output Test#12aw212 mean constructors are non-static?
Your second example hits the spot. this reference is available in the constructor, which means constructor is executed against some object - the one that is currently being created.
In principle when you create a new object (by using new operator), JVM will allocate some memory for it and then call a constructor on that newly created object. Also JVM makes sure that no other method is called before the constructor (that's what makes it special).
Actually, on machine level, constructor is a function with one special, implicit this parameter. This special parameter (passed by the runtime) makes the difference between object and static methods. In other words:
foo.bar(42);
is translated to:
bar(foo, 42);
where first parameter is named this. On the other hand static methods are called as-is:
Foo.bar(42);
translates to:
bar(42);
Foo here is just a namespace existing barely in the source code.
Constructors are non-static. Every method first parameter is implicit this (except static) and constructor is one of that.
Constructors are NOT static functions. When you do Test test =new Test(); a new Test object is created and then the constructor is called on that object (I mean this points to the newly created object).
The new keyword here is the trick. You're correct in noting that in general, if you're calling it without an object, a method is static. However in this special case (i.e., preceded by the new keyword) the compiler knows to call the constructor.
The new operator returns a reference to the object it created.
new Test(); // creates an instance.
The System.out.println(this); is called after the new operator has instantiated the object
Not static. Read about constructors http://www.javaworld.com/jw-10-2000/jw-1013-constructors.html.
Neither.
Methods can be divided into 2 types: static/non-static methods, aka class/instance methods.
But constructors are not methods.
When we talk about static class then it comes to our mind that methods are called with class name,But in case of constructor ,Constructor is initialized when object is created So this proves to be non-static.
Constructors are neither static (as called using class name) or non-static as executed while creating an object.
Static:
Temp t= new Temp();
The new operator creates memory in the heap area and passes it to the constructor as Temp(this) implicitly. It then initializes a non-static instance variable defined in a class called this to the local parameter variable this.
Below example is just for understanding the concept, if someone tries to compile it, it will give the compile-time error.
class Temp{
int a;
Temp this; //inserted by compiler.
Temp(Temp this){ //passed by compiler
this.this=this; // initialise this instance variable here.
this.a=10;//when we write only a=10; and all the non-static member access by this implicitly.
return this; // so that we can't return any value from constructor.
}
}
Constructor is static because:
It is helping to create object.
It is called without object.
Constructor is used to initialize the object and has the behavior of non-static methods,as non-static methods belong to objects so as constructor also and its invoked by the JVM to initialize the objects with the reference of object,created by new operator
I have a class that holds another objects inside it (List, Set and objects from my application).
public class SomeClass {
private List l;
private SomeObject obj;
//...
}
Is a good practice instantiate these objects where the SomeClass object is created to avoid NullPointerException? Something like:
public class SomeClass{
private List l = new ArrayList();
private SomeObject obj = new SomeObject();
//...
}
In a normal way, these objects will be generated in some processing/analysis, but errors can occur and the objects still with null value.
Yes, it is a good practice to do so. The constructor is a natural place to instantiate member objects. You can also create them right where they are declared:
private List l = new ArrayList();
However, it might be a good idea to restructure or modify your code so that NullPointerExceptions won't occur, regardless of the order in which the methods are called.
If an empty List or a default object of that class is a valid state in every following operation, yes, instantiate a default. However, if the default would be an invalid state, don't do it.
Well I prefer to initialize because sometimes is a headache to find where's the null pointer exception, and if u initialize your objects with constructors the object inside should be initialized.
Hope this help you.
It's generally good practice to instantiate member fields (whether objects or primitives) at creation time whenever the default value (0, false, or null) is not what you want. One time to defer this is for lazy instantiation. (This is used, for instance, when an object might not be needed after all and creating it is expensive.) Another time to defer this is when other initialization needs to take place beforehand.
Assuming you want to initialize a field at object creation time, there are two ways to do it: with an initializer expression as you showed or in the constructor(s). There isn't too much difference, other than that instance initializers run before the first line of the constructor. This may or may not cause problems, depending on your code logic.
It's also a good idea to declare member fields final whenever they are initialized at object creation and are expected to not change during the life of the object. A side benefit of declaring a field final is that the compiler will catch any failure to initialize it. (The compiler requires definite assignment to consider a final field to be properly initialized.)
You are talking about eager construction versus lazy construction. There are places where each has value.
In many situations, it is better to lazily create things as it saves memory. But then you must check for null every time you try to get data
In some situations, it makes sense to create the object upfront, either to avoid the null checking mentioned above or to avoid the object creation time hit during an intensive process
It is normal to generate them like this, but it's not a nice way to code to generate them just to avoid NPE. There should be proper validation in code, rather than assigning garbage-eligible objects which won't be utilized.
You can also assign some default states - like Collections.emptyList(), or
in a constants class:
DEFAULT_STATE = new SomeState();
then simply
class A {
State obj = Constants.DEFAULT_STATE;
}