Is it a good practice to create an Object inside a loop. I am pointing towards the following code:
for(some condition){
SomeClass a = new SomeClass ();
System.out.println(a);
}
So this would create a new instance of SomeClass for each iteration. So number of instances will be equal to number of iterations. And then these will later be collected by GC.
Is it better to reuse a SomeClass object inside the loop. Something like this:
SomeClass a = null;
for(some condition) {
a = new SomeClass();
System.out.println(a);
}
As far as I understand this, the second way is better as this will just create the SomeClass object once and will reuse it in every iteration. But I am doubtful. Please confirm this, or let me know where my fundamentals are incorrect.
The difference is that in your second case, your a variable will still be in scope when the loop is over
other than that, they're essentially the same, even from a garbage collection point of view.
Strings are reference types(albeit immutable ones), and it doesn't really matter whether you declare a new variable for them or just overwrite the same variable each time. You're still creating a brand new string every time.
Be careful not confuse the 'Object' itself and a 'Reference' to an 'Object':
For instance the following code creates a (null) Reference, but no object is created.
Object a = null;
The following code create boths an Object AND a reference to that object (the reference is held in a variable called 'a'):
Object a = new Object();
The following code creates new Object and 'repoints' an existing (reference) variable to point to the new Object: if the variable 'a' already held another reference, 'a' forgots it. [but that doesn't mean other variables may still point to the old object referenced by 'a'].
a = new Object(); // it is the reference 'a' that is 're-used' here not the object...
Everytime you re-run the that statement above in your loop; you are indeed creating a new object ; and you are 're-pointing' 'a' to that new object.
The previous reference (i.e. reference held in 'a') will be forgotten each time; and (assuming we have a single-threaded program here) that means the object it pointed to will have zero references pointing at it now: which means the object is eligible for Garbage Collection. Whether this Garbage collection happens or not at this point in time - I don't know I'm afraid.
But I would say : that there is no difference in your coding examples in terms of when Garbage Collection happens; whether or not the 'pointer-type' is already defined as an 'Object' outside of the loop, or repeatedly redefined within the loop.
The following (useless) examples might help illustrate the difference between the 'Create-an-Object' and 'Point-a-Reference' actions that the code does in one go:
// This creates an object ; but we don't hold a reference to it.
public class TestClass {
public static void main(String[] args) {
for (int n=0;n<100;n++) {
new Object();
}
}
}
And to contrast:
// This creates a reference ; but no object is created
// This is identical to setting the reference to 'null'.
public class TestClass {
public static void main(String[] args) {
for (int n=0;n<100;n++) {
Object o;
}
}
}
Both create an equivalent amount of strings because String is immutable. Anytime a String is assigned a new value, a new String is created.
Let's assume you meant to use a mutable object in your example.
Option 1
for(some condition)
{
Object o = new Object();
System.out.println(o);
}
This will create a new Object o for each iteration of the loop.
Option 2
Object o;
for(some condition)
{
o = new Object();
System.out.println(o);
}
This will create a new Object o for each iteration of the loop.
Even for a mutable object, you get the same result either way!
the 2nd is not "better".
String a="foo"; reuse a literal string from string pool. That is, no matter you declare the a in/outside the loop, there is no difference in terms of memory. But they have different scope. I think it is another issue.
even if with your edited version, with general SomeClass, it is not like what you thought:
the second way is better as this will just create the SomeClass object once and will reuse it in every iteration .
It creates new object in each loop step. a is just a reference to the object. The point is, if the object(s) you created referenced by other objects, GC will not collect it, and release the memory. For example, the old (<=java1.6) String.subString() method, it holds the original String as char[], so GC won't clean the original String.
You are confusing the variable you assign an object to, to the actual object instance.
Both code samples create the equivalent amount of objects. The second one will keep one instance in larger scope, thus it will be available for a longer time.
according to my knowledge - in bigger application (not in this) but in bigger is better to use static block for object creation - because static block code is executed only once when class is loaded into memory. Technically, you can can have multiple static blocks in a class, although it doesn’t make much sense
remember: Static block can access only static variables and methods
The only difference is that in the second case, variable will still be in scope when the loop is over ,no. of objects that are created in both the cases are equal as Strings are immutable
as you have just edit the question still in this case new Objects are created in the memory at each iteration in both the cases
Since the topic has changed quite a bit. I update:
If you really want to reuse the once create object you will have to write that code yourself. It could follow this principle:
SomeClass a = new SomeClass();
for(some condition) {
a.reset();
//do something with a
}
Where the SomeClass.reset() method handles all the details (which are dependant on your actual usage of the object).
it is all about scope,
if you do your second way:
SomeType someFunction(){
...
SomeClass a = null;
for(some condition) {
a = new SomeClass();
System.out.println(a);
}
...
return something
}
object a will exist in memory till end of someFunction while for first method, its lifecycle is within single iteration of loop
Related
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.
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];
I think this question is a bit confusing without looking at any code, so here is my example:
This:
public class Example {
public Object foo() {
return new Object();
}
}
vs this:
public class Example {
private Object object;
public Object foo() {
object = new Object();
return object;
}
}
Does the 2nd example just switch the memory address of the instance variable and not create a new one? Does doing it the 2nd way save memory?
The reason I ask is because the method could very likely be called very many times during the runtime of the program.
Thanks!
Does the 2nd example just switch the memory address of the instance
variable and not create a new one? Does doing it the 2nd way save
memory?
No, the new instance will be created in a new location in memory.
The existing memory will not be available until garbage collection has determined there are no references to the existing instance.
Does it save memory? No, it uses more memory. Because now every instance of Example has an inaccessible field Object. And calling get on it replaces the current local value with a new value before returning the new reference. Meaning the old reference is irrelevant.
The second example actually uses more memory than the first example because now each instance of Example must be big enough to store a reference to an Object. I believe you meant to write
public class Example {
public Object obj = new Object();
public Object foo() {
return obj;
}
}
Now this example has the same memory requirement, but this does have the added benefit of not reallocating an Object every time foo is called. Which will save memory if you call foo() repeatedly.
I suggest you to use jvisualvm or jmc to check both codes.
Run each code with decent and similar scenario. Both tool I mentioned will report memory consumption and garbage collection.
I just want to make clear that to call a function in two forms like
By creating an object and calling the method by using that object.
Without creating a object calling the function.
I mean for instance i have a class like
Class A{
public int callMethod(){
return 2;
}
}
Now I am creating another class to call the method callMethod defined in the Class A
Class B {
public static void main(String[] args) throws ParseException {
A a = new A();
//1st form to call the method
int aa = a.callMethod()
System.out.println(aa);
//2nd form to call the method
aa = new A().callMethod();
System.out.println(aa);
}
}
here in the first statement after creation of a object i am calling the callMethod() of class A by using the class object of A. And in the second time i am calling the method directly without creating the object class A. In the first form calling the method it is damn sure that we are creating the object and occupies some space in the memory for the object. Then what about the second form calling the method? Will it take any object creation? Which one is quicker? can anyone give me the clarifications on this.
When you use new keyword and constructor, in this case, new A(), it is creating a new object.
And in the second time i am calling the method directly without
creating the object class A.
That's not true - the object is still created, it only has no name you can refer to afterwards.
Both of your ways are creating an instance of the object but in second case you don't have variable to point to the object if you want to access the second object later you can not do it
In the second code you are creating an instance of A and it is occupying space on the stack.
The first code will require that you instantiate A on the heap space (Unless you instantiate it from static code, for example:
static {
A a = new A();
}
)
You are creating objects in the BOTH the methods. The statement
new A()
creates a new object and then you are calling a function.
You should also know that objects DO NOT get different memory space for methods. All the objects of a class share the same memory space for methods. so it really doesnt matter about the space.
If you want to call a function without using a object, you should make the function static, that way you cam call the function without actually using an object.
hope this helps.
Read about stack space and heap space in java
In java we have references referring to objects on heap space,
In both cases, it is creating object on heap space but in first case
you have reference stored on stack space with A a ("a" is reference)
So in same method or any other methos to which this reference is
passed can refer to the original object (first object created) from
heap space...
In second case you are calling methos directly on new obj which has no
reference stored on stack space to refer it afterwards like in first
case.
Both are same..!!
When you write
new A();
here Compiler calls the Non-parameterized constructor (if it is not written by programmer compiler calls the default constructor )
like:
A()
{
//i am default constructor
super();
}
note: here super(); call the immediate super-class default constructor which is the Object class and object is created.
A a = new A();
here object is created and you assign that object to reference 'a';
I am currently creating an Android app and thought that I had a problem with saving data internally, etc. It turned out that the problem had nothing to do with that, but with my understanding of Java.
The problem is that when I do
myObject1 = myObject2;
and use myObject1 in myObject3 which might be a list, or whatever (in my case a Hashtable) and then change myObject2, myObject3 gets changed accordingly, as well. What is this called, and where can I learn more about it? How do I assign myObject2 to myObject1 so that myObject1 is completely "independent"?
Variables that are Objects in Java are called references and refer to the same location in memory. If you want two objects of the same type that don't refer to the same location in memory in need to allocate memory for them on your machine by using the new keyword.
Below both variables myObject1 and myObject2 are references to an OBJECT1 object, but that don't exist at the same memory location:
OBJECT1 myObject1 = new OBJECT1();
OBJECT1 myObject2 = new OBJECT1();
If assigning an object to another is important you can look into the clone() method or use a copy constructor:
public OBJECT1(OBJECT1 toCopy)
{
this.field1 = toCopy.field1;
this.field2 = toCopy.field2;
this.field3 = toCopy.field3;
this.field4 = toCopy.field4;
}
Those variables are references to an object; think of each variable as the end of a string. The other end is tied to an object. If you assign a variable, you're tieing a new string onto an object.
To create a copy, you (unsurprisingly) need to create a copy. Sometimes, this is easy: there might be a copy constructor that lets you do this:
ArrayList<String> copy = new ArrayList<String>(oldArrayList);
Other times, you may be a method that makes a copy; for example, some classes implement the clone() method:
Foo copy = (Foo) otherFoo.clone();
You just have to study the API of a class to find a way to copy an object.
That depends on what myObject is. The word you are looking for is clone if you want to have an exact copy. But not all Objects support clone, so you may have to build your own clone method that (as #Hunter) pointed out needs to allocate new memory through the new keyword.
So in Java or in any OOP language
if you consider the statement
Object obj = new Object()
obj is called the handle which actually points to the location where the actual Object is stored.
so when you do obj1 = obj you are getting 2 handles which are actually pointing to the same location
so if you do obj1.setSomething() it will be reflected on the obj.getSomething() call also.
Variables contain references to objects. In other languages, references are often called pointers. So doing myObject1 = myObject2; makes the myObject1 variable reference the same object as the myObject2 variable.
If you want to make a copy of an object, the best way is to implement it yourself, for example using a copy constructor:
public MyClass(MyClass other) {
this.foo = other.foo;
this.bar = other.bar;
...
}
and thus do
myObject1 = new MyClass(myObject2);
When you assign an object o1 to another object o2 you make the o2 pointing to o1. So whenever you change object o1 object o2 changes accordingly.
It happens the same with objects inside a list. This is because in Java when you assing an object to another you don't copy the content but it is like you "share" it.
The only way to create another object indipendent from everything is using new and then copy each attribute.