Difference between "ClassA object = new ClassA();" and "new ClassA();"? - java

I don't know if this has already been asked since I can't find it anywhere.
So, recently I came across this feature in IntelliJ IDEA where it says transform expressions.
Here is the picture:
What I want to know is that what is the difference between ClassA object = new ClassA(); and new ClassA();.
Is there any functional differences or anything else that may impact normal code functioning in any way?

If your code contains a variable
ClassA object = new ClassA();
which you never use later in the code, you can eliminate the variable and the new ClassA() expression.
However, if creating an instance of ClassA() has some side effects relevant to your program (i.e., you need the constructor of ClassA to be executed even if you don't do anything with the created ClassA instance later), you can replace that statement with a statement that creates an instance without assigning it to a variable:
new ClassA();
Such a statement makes it clear that the created instance is not expected to be accessed later by following code.
However, both statements will function the same (though the first statement may result in a warning saying you declared a variable that you are not using).

If you use new ClassA() and don't do anything with it, that instance is unreachable unless you're storing it somehow, somewhere (for example, in a List). If it has any side effects, however (like printing), those side effects will still occur. If you use ClassA object = new ClassA();, you'll be able to use that specific instance later in the code due to the name binding.
You'd normally use new ClassA() when you want it to be anonymous because you don't need a long-standing reference. For example:
List<ClassA> instances = new LinkedList<>();
for (int i = 0; i < 100; i++) {
instances.add(new ClassA());
}
or
void doSomethingWithClass(ClassA c) {
// do something
}
doSomethingWithClass(new ClassA());

By this statement, ClassA object = new ClassA(); , you are creating a reference. Whereas when you write new ClassA(); It is an anonymous object that you are creating. It is to be noted that If you have to use an object only once, an anonymous object is a good approach.
See more info about anonymous objects here

There is no difference. Two instances have been created for ClassA. one instance is called "object" and the other instance is "anonymous".

Related

Calling methods on reference variable vs Calling methods on a new object

I'm having confusion in calling a non-static method
class A {
void doThis() {}
public static void main(String... arg) {
A a1 = new A();
a1.doThis(); // method - 1
new A().doThis(); // method - 2
}
}
I know that both method-1 and method-2 will call doThis(), but is there any functional difference?
There won't be any difference in execution of those methods but in case of new A().doThis() your're going to lose the reference to the instance of an object you've invoked the method on and you won't be able to use it further in your code. All the changes this method could've done to internal state of the instance will be lost.
In case of A a1 = new A(); a1.doThis(); you're going to preserve the instance of an object (in variable a1) and potential changes made to its state made by method doThis(). Then you'll be able to continue working with this object.
Is there any functional difference?
Both will behave in the same way.
The second option doesn't allow you to reuse that instance again. It may be convenient and concise in one-line return statements (for instance, consider the builder pattern where each constructing method returns a half-initialised instance):
return new Builder().a().b().build();
or if an object was created only to perform a defined action once.
What will be the reference of a new object in method-2?
It is no longer exist (more precisely, we don't have access to it) unless the doThis returns this which you could be able to put in a variable after method execution.
Can I say that method-2 is an improper way of calling a non-static method?
No. Why should we create a variable if this variable will never be used afterwards?
Let's see what the code says in plain English:
A a1 = new A();
a1.doThis();
Create a new instance of A.
Store a reference to it in the variable a1.
Call doThis() on our instance.
Whereas new A().doThis(); reads as:
Create a new instance of A.
Call doThis() on our instance.
So the only difference is whether you store it in a local variable or not. If you don't use the value in the variable any more, then that difference doesn't matter. But if you want to call another method on the same object, let's say a1.doThat(), then you're in trouble with the second solution, as you haven't got a reference to the original instance any more.
Why would you want to use the same object? Because methods can change the internal state of the object, that's pretty much what being an object is about.
Lets take a look at both these methods one by one.
Method-1
A a1 = new A();
a1.doThis();
In method-1, you have a reference of newly created instance of A, i.e a1 and you can call as many methods on this instance of A using this reference a1. Basically you can reuse that particular instance of A by using its reference a1.
Method-2
new A().doThis();
However in method-2, you don't have any variable that stores the reference of your newly created instance of A. How will you refer to that particular instance of A if you have to call any other method on that particular instance of A ? You will not be able to re-use that instance of A if you create an instance using method-2 and you will lose that instance as soon as it is used.
case1:
A a1 = new A();
a1.doThis();
The above two line means object created and doThis(); executed but still object available in the heap memory.
case2:
new A().doThis();
A class object created and doThis(); executed after immediately GC(GarbageColletor) will activate to remove the A object from the heap memory bcz it's a non-referenced object and we can call this object as an anonymous object.

Casting to parent changes object reference?

I'm doing some work with jesque, workers and pipelines. I'm ok with that; the thing is that I have a new feature. I have a class named FileAnalysis, so it has some common attributes, but it is not abstract enough; it is still very focused on the task it was made for.
I made another feature before and was able to reuse this FileAnalysis. But this time there are new key properties for the feature I'm working on, so I created a new object ContactFileAnalysis with the additional properties.
A FileAnalysis consists of the main object, which is then parsed to JSON and stored in redis. This is done through a manager; this manager reads/writes to redis, and recreates the FileAnalysis object. There is a support object to update the state of the file analysis in a pipeline; it's called:
FileAnalysisUpdater(FileAnalysis).
If I make a new manager which is able to handle ContactFileAnalysis, this objects holds new properties and the new manager will store them in redis correctly. Then it calls the updater in a pipeline. What I want to achieve is to invoke
ContactFileAnalysis contactFileAnalysis;
updater.Update((FileAnalysis) contactFileAnalysis);
When I cast to a parent object and the pipeline is done, will contactFileAnalysis be updated by the updater? Or does this cast change the object reference and therefore no change is reflected?
I want to reuse this functionality because there are no changes in it; the behavior is the same, the information is the same; I just need to propagate new information, and to do so I persist it in redis, but from there on it's the same; the updater doesn't need anything from my new object.
P.S.: I know it is safer to write every involved object again and make sure it works with the new FileAnalysis, but this means a lot of code for a feature that is hardly used and not that important. Also, I work for this project and it's not easy to approve a PR of 4k lines of code.
As user2864740 pointed out in a comment, casting an object reference never changes the reference. You can test this easily enough:
Object obj = null;
String str = "foo";
obj = (Object) str; // Unnecessary! See below.
System.out.println ("Is str == obj? " + (str == obj));
However, that casting to the parent is likely unnecessary. Hopefully you declared ContactFileAnalysis to be a subclass of FileAnalysis:
public class ContactFileAnalysis extends FileAnalysis
If so, then any reference to an instance of ContactFileAnalysis is always considered a reference to an instance of FileAnalysis. In fact, it's also a reference to an instance of FileAnalysis' superclass, and so on up the line (to java.lang.Object, the parent of all java objects). Which means my cast to Object in the sample code was unnecessary:
obj = str; // This works, and is considered proper style.
It's also unnecessary to cast it to pass it to updater.Update(). (Another style note: methods should start with a lowercase letter.)
updater.Update(contactFileAnalysis); // Probably fine. See below.
Note that if you didn't declare ContactFileAnalysis to be a subclass of FileAnalysis, you will have to cast it. (This could happen if you instead had a class that implemented two interfaces, had a reference to an instance of it typed to one of those interfaces, and wanted to pass it to a method that took an instance of the other.)
Another note: if for some reason you had two methods as follows:
public void update (FileAnalysis fa) { /* code */ }
public void update (ContactFileAnalysis cfa) { /* ugh */ }
And you made a reference to a ContactFileAnalysis instance, and passed that to your updater:
ContactFileAnalysis myCFA = new ContactFileAnalysis();
updater.update (myCFA);
It'll use the second update - the one defined to take a CFA. Cast it, however:
updater.update ((FileAnalysis) myCFA);
and it'll use the first update. Same thing happens if you set a FileAnalysis variable to it.
FileAnalysis myFA = myCFA;
updater.update (myFA); // uses the first update, even though it's a CFA
Hopefully you understand why. If not, check out the official documentation on inheritance.

Why is it OK to not store the result of 'new' in a variable

I have been told that the new keyword create an instance of a class and returns an object that is stored in memory and is assigned to a variable of the class type. If the statement in bold is true, why is the statement below not incorrect?
new Class();
Because there is no variable assigned to class, while new returns a variable?
Who told you that new does what you say it does? new creates an object and returns the reference to that object. It doesn't assign anything to anyone because the assignment operator in java is =
Here's an excerpt from the java tutorial:
The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. The new operator also invokes the object constructor.
Java Tutorial
The "creates an instance of a class and returns the object address that is stored in memory" part is mostly right, except that it's technically Java's own representation of the object's location rather than the actual memory address - "reference" is a better term. The "assign it to variable" part is not related to new at all; the assignment is done by =, e.g. Class c = new Class().
If you don't have a =, the address won't be assigned to anything. This is usually pointless since it amounts to throwing the new object away, but it is legal because it is sometimes useful (if the constructor has some side effect that you're interested in). It is also legal to use the reference returned by new to call a method, e.g. new Class().doSomething(), or to pass it as a parameter: doSomethingElse(new Class()).
The above statement is not wrong because the code invoking the constructor is choosing to do nothing with the reference to the object.
Perhaps a project has an all encompassing class used to initiate view behavior. You might choose to instantiate an instance of a custom view class within the main method to mimic this behavior:
public static void main(String[] args) {
new MyClass();
}
Then in your MyClass object:
public class MyClass {
public MyClass() {
//do stuff here
}
}
new is a Java keyword. It creates a Java object for the class and object address that is stored in memory. It also allocates memory for it on the heap. new is also used for array creation, as arrays are also objects.
Example -
int[] intArray = new int[10];
String[][] stringMatrix = new String[5][10];

Constructors does not have any return types but then how object is created?

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.

What is the proper way of creating objects in Java?

Which method is better?
Creating objects in class constructor:
public class Menu {
private JButton start;
// ...
public Menu() {
start = new JButton("Start");
// ...
}
}
or creating objects while variable declaration?:
public class Menu{
private JButton start = new JButton("Start");
// ...
public Menu(){
// ...
}
}
and what is the difference?
Both variants are OK , but I prefer the second one since there's one statement less - to write, but more important to read and to maintain.
There is no runtime difference in this case, AFAIK.
Sometimes, when following the second variant, you can even remove the custom contructor altogether.
Already answered here , The question was for C#, but the logic is still the same.
It is said to follow these rules, which are pretty complete:
1. Don't initialize with the default values in declaration (null, false, 0, 0.0...).
2. Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
3. If the value of the field changes because of a constructor parameter put the initialization in the constructors.
4. Be consistent in your practice. (the most important rule)
Read the comments for more details.
Initialisation within the constructor does allow you to deal easily with exceptions, which can be helpful as your code base matures.
But some folk say that declaration at the point of initialisation is more readable. But then the order that fields appear in the source becomes important.
Aside from the exception consideration, it's down to personal opinion.
The second method is better.
There are four different ways to create objects in java:
A. Using new keyword
This is the most common way to create an object in java. Almost 99% of objects are created in this way.
MyObject object = new MyObject();
B. Using Class.forName()
If we know the name of the class & if it has a public default constructor we can create an object in this way.
MyObject object = (MyObject) Class.forName("com.sample.MyObject").newInstance();
C. Using clone()
The clone() can be used to create a copy of an existing object.
MyObject anotherObject = new MyObject();
MyObject object = anotherObject.clone();
D. Using object deserialization
Object deserialization is nothing but creating an object from its serialized form.
ObjectInputStream inStream = new ObjectInputStream(anInputStream );
MyObject object = (MyObject) inStream.readObject();
There is no difference. I usually prefer to use the second way, but if you need to have exception handling, then you need to use the first way.
With the first option you could add more logic to object initialization (exception handling, logging, etc..).
NOTE: if you would like to consider Dependency Injection at some point then initialization on declaration is not an option.
You can create objects in different ways. As Neeraj already said Lazy Initialization can sometimes be the preferred way.
In your example, where you need your button as soon as the parent Object is instantiated, you can use both ways.
But you can also consider the following example, where you create the child object exactly at the time you need it.
public class MyObject{
private List<String> myList = null;
public MyObject(){
//do whatever you want
}
public void add(String toAdd){
if(myList == null){
myList = new ArrayList<String>();
}
myList.add(toAdd);
}
}
You can craete object both way and i recommend you to use
JButton start = new JButton("Start");
Best way is to create and initialize object in the constructor of a class.

Categories