Java List/Array List clarification - java

If someone can explain the difference between these two type of Array Initializations that would be great:
There is a static method getList() in class ListReturn, which returns an ArrayList<Some_Custom_Object> upon calling.
In the invoking class, I can call the function in two ways as follows:
List<Some_Custom_Object> listFromCall = new ArrayList<Some_Custom_Object>();
listFromCall=ListReturn.getList();//works completely fine
List<Some_Custom_Object> listFromCall = ListReturn.getList();//Works completely fine
My question here is, in the second scenario, don't we have to initialize or instantiate the listFromCall object?, can we directly assign return values from method to un-initialized List/ArrayList object?
Can someone please explain what is going on beneath the hood here?.
Thanks

You only have to initialize a variable if you read from it before you write to it.
If you write to an uninitialized variable, the computer doesn't care because you're initializing it with the return value from ListReturn.getList().
In fact, you shouldn't needlessly initialize object variables to anything but null if they're going to be overwritten before use. Otherwise, you create and garbage collect an extra object for no reason.

Let's discuss both way one by one,
First Way :
List<Some_Custom_Object> listFromCall = new ArrayList<Some_Custom_Object>();
means, something likewise,
listFromCall=ListReturn.getList();//works completely fine
it will reflect on listFromCall's value assignment, see below image for
deeper understanding,
Here, completion of both statement, total either 2-object created(1
will eligible for garbage collection after second created and assign)
or 1-object created (which will become eligible for garbage collection
and assign null to reference variable)
Your Second Way :
Now if you do something likewise,
2. List<Some_Custom_Object> listFromCall = ListReturn.getList();//Works completely fine
Then it will appear something likewise,
So, here either 1-object(of ArrayList) will created on heap or not.

Related

Java Difference between { Object a = new Object(); a.getVariable() } and { new Object().getVariable() }

i don't know if its asked before (i searched but couldn't find)
Is there any difference between the following 2 code blocks?
1:
// Let's say we want to get variable from non-static object
Object a = new Object();
int varWeWant = a.getVariable();
2:
int varWeWant = new Object().getVariable();
as you see second option is one-line code
and i know the java, both codes create object first and retrieve variable via method but i'm not java expert so i wonder if they have any differences ?
Sorry if it is silly question :D
i was just wondered this for too long
thanx
The first creates an object that can be referred to later, then calls a method on it.
The second creates a temporary object that can only be used to call that single method.
Really, if you're using the second way, you should question if the object was necessary in the first place. It might make more sense to just make that method a standalone function unless you're using the Builder or similar pattern.
both produce the same BUT option 2 is the object instance an anonymous reference... that means you can not do anything with that object after that statement...
int x = new Object().getVariable();
This is done when the object have one time use.
Object a = new Object(); //Creates an object named a
This is done when object has multiple variables and functions. This way object is created only once and the variables and functions are called. If we were to use new Object().getSomeFunction() every time then new object is created every time. Its expensive memory wise and more lines has to be written.
The result in varWeWant is the same.
Some minor differences:
In the first version you can later use the Object for other purposes, as you stored a reference to it in the a variable (that's obvious).
Introducing the variable a comsumes a small amount of memory.
As long as the variable a refers to this Object, the garbage collector cannot reclaim its memory. (But compiler and runtime optimizations might be able to free the memory earlier, as soon as a is no longer used).
Storing the reference in a variable will take a tiny amount of time.

Anonymous variables (?) advantages?

I was wondering about one thing that jumped into my mind yesterday.
I apologize in advance for the misleading title, but I really don't know how to entitle this.
Well, suppose we are two objects ObjA and ObjB, and that, for instance, ObjB has a method that takes an ObjA object as argument.
We can do this (taking java as language):
ObjA instanceA = new ObjA();
ObjB instanceB = new ObjB();
instanceB.method(instanceA);
or
new ObjB().method(new ObjA());
Assume this is the body of some function, so the objects will be destroyed when going out of scope.
My question is:
do we get a performance advantage by not instantiating the singular objects and calling the implicitly as for the second code? Is this readability sacrifice worth something? Or is it all for nothing since the implicitly created objects will be stored in memory and die by scope anyway?
Note: I don't know if I'm saying right with "implicit" or "anonymous", but I have not found much on Google.
Absolutely no difference performance wise.
But in few cases, you will be forced to use first type.
For ex :
ObjA instanceA = new ObjA();
// Do something with instanceA
instanceB.method(instanceA);
If you have nothing to do in middle, I can just use the second way to save a line of code.
In this case readability is the only advantage one way or another.
There's no significant performance or memory benefit.If you store a reference in a local variable and then invoke the method,there may be an extremely small performance penalty for storing the reference.
The anonymous object is created and dies instantaneously. But, still with anonymous objects work can be extracted before it dies like calling a method using the anonymous object:
new ObjB().method(new ObjA());
We can’t use twice or more as the anonymous object dies immediately after doing its assigned task.
The first approach using named variable is required if you need to store the object to use it several times without creating new objects or to store the current result of some method returning an object if there is a risk (e.g. because of multi-threading) the result will be different the very next time. In other cases it's more convenient to use anonymous objects since their scope is the same and there is no namespace cluttering with unneeded identifiers.

In java, how can we destruct an instance of a class from a method within the class

I approached it similar to the case of deleting any usual object, ie, simply making the reference null and letting the Garbage Collector do its job.
However for equating to null within a class, the only reference to the object is "this". So is the code for the following class valid:
class A{
public A(){
//Init
}
public void method destruct(){
if(someCondition){
this=null; //Is this statement valid? Why / Why not?
}
}
}
You don't "destruct" objects in Java. This is wrong-headed. Don't do it.
Objects are created on the heap in Java. They live as long as there's a reference that points to them. The garbage collector cleans up the mess.
You should certainly do what you can to make sure that you don't accumulate and hold onto references unnecessarily (e.g. Listeners in Swing).
But your proposal is not the right thing at all. Cease and desist.
this=null; //Is this statement valid? Why / Why not?
It is not valid Java because this is not an lvalue; i.e. not something you can assign to. This is a compilation error, just like 42 = i; is a compilation error.
(The JLS says the following about assignments: "The result of the first operand of an assignment operator must be a variable, or a compile-time error occurs." - JLS 15.26.1 The JLS text then goes on to list the different things that qualify as variables, and this is not one of them.)
Besides, as duffymo says, it is a totally wrong-headed thing to do in Java. Just let the GC do its job.
NOTE: What you suggest is highly unlikely to be useful.
What you can do is use delegation.
class A {
private AImpl impl = new AImpl();
public void close() {
if (impl != null)
impl.close();
impl = null;
}
}
As all references are indirect, you can ensure there is only one reference to the real object and clear it.
Proxies in some OSGi containers do this when a component is unloaded. As the container has little control over the lifecycle of the references, it would make it difficult to ever unload a library (the implementation).
Your goal is deeply misguided.
Either someone outside the instance holds a non-weak reference to it. Then it will not be collected no matter what you do inside. Or no one does, then it will eventually be collected, no matter what you do inside. In either case, this=null would make no difference, even it were legal java code. Don't do it. If you are concerned about object lifetime and memory exhaustion, look out side the object that you want to get rid of.
Setting this = null is like trying to say that an object doesn't reference itself. It always implicitly references itself. You need to find what other objects might be referencing this one and clear their references instead. Usually, this happens automatically because most objects are retained through local variables that are on the stack. When I say "retained" I mean that they are referenced through a chain of references that ultimately leads to a variable on the stack. When you leave the method, the reference is cleared. But if you have a static variable referencing this object that might be a case where you must explicitly set it null.
For the java garbage collector to pick up your class it should not be referenced be OTHER classes.
The statement this=null; is illegal because the left hand side of an assignment must be a variable.
There is no way to explicitly delete the particular reference in Java. Java does this to avoid hanging references. If you delete an object then other objects refer to it can potentially try to access the data and get a reference to invalid data.
You shouldn't be trying to delete objects anyways, just move all references to the object to null.
No. An instance object could be deleted by the GC when no reference points to it, that its, from all running threads could not navigate till the object. When you are in the object executing a method, this method is invoked from outside, so there is a reference to the object. The object itself can not be destroyed, as a reference to it still remains outside.
Consider another approach for memory management.
In methods this is reference to object on which current method is invoked so it should not be possible to changed it. Think of this as final reference.
Life cycle of objects are ruled by the JVM, due this reason an object cannot decide when itself is no longer needed. What you could do is put some effort on the references to this object. Type of references could be used in order to point the "importance" of the object.
The basic types of references in java can be found here:
More here: http://docs.oracle.com/javase/1.3/docs/api/java/lang/ref/package-summary.html
Discussion about the references here:
What is the difference between a soft reference and a weak reference in Java?
and
Understanding Java's Reference classes: SoftReference, WeakReference, and PhantomReference
You can call :
System.gc() or RuntimeUtil.gc() from the jlibs
but if you do that you mess with the JVM runtime.
If you set refernce to null, the object still exists , its just its' reference won't refer to this object and at the next time GC will be invoked it will destroy the object(unless other references refer to it).
No the above code is not valid. The reference this of a class only lasts as long as the JVM is being executed. Setting this == null will infact give you a compiler error because though this is termed as reference it is actually a value and you can't assign anything to a value.
Also it is unnecessary since this is valid for only as long as the execution is in that code and GC cannot claim an object which is still executing. However as soon as the execution ends for the object, this will also be lost and the object will automatically become available for GC (i.e. if no other reference to the object exists)
This is a compilation error. You cannot assign NULL to 'this'. Keyword 'this' can be used on the right side of equals (with the exception that left hand is not NULL. Reason: nothing can be assigned to null).
For destruction,in java, you have a GC who can do this job for you behind the scenes.
Please note that for user defined objects you can still do something like -
object reference = null;
However 'this' cannot be used on left side of equals.
The very reason why the execution thread is inside the destruct() method tells me that there is a caller that is holding a reference to this instance of class A. So, nevertheless, you cant do anything like "this = null" in java - it would not have helped, even though it was allowed in java. You cant destruct to objects in java.

How to pass mutable objects by value to java

Is there any way that I can pass mutable Objects by value to a function in java?
What I actually want is to pass an object to a method, do some operations on it (change it) and again call that method with that old object only(not the changed value).
here is some sample:
{ MyObj obj = new MyObj(); obj.setName("name");
append(obj);
System.out.println(obj.name);
prepend(obj);
System.out.println(obj.name);
}
void append(MyObj obj){ obj.name+="1"; }
void prepend(MyObj obj){ String a = "1"; obj.name=a+obj.name; }
At the end of this code, I want output as:
name1
1name
Objects themselves aren't passed at all in Java. Ever.
But everything is passed by value - where the only things that can be passed are primitive values and references.
It's not quite clear what you're trying to do - is the idea that you'd like to have a method with (say) a StringBuilder parameter, but without any changes made to the object from within the method being visible to the caller? If so, you basically need to clone the object yourself.
Unfortunately, no. Java never passes Objects by value, it passes the reference of the object by value.
Explanation from here:
What's really happening is that
objects are always held by reference
in java -- never by value -- and the
references are, indeed, being passed
by value.
Why do you need to do this? If you don't change the object, then it doesn't matter. If you do change the object, and don't want to affect the caller's object, then just make a copy locally. But I would guess that at least 90% of the time people think they need to do that, they really don't.
Show some code. What are you really trying to do?
AFAIK immutable/mutable is not related with passing by value/reference. Strings are passed by reference, not value. What makes string immutable is design of string class itself.
Perhaps you may explain a bit more what you looking for.

Why does javac complain about not initialized variable?

For this Java code:
String var;
clazz.doSomething(var);
Why does the compiler report this error:
Variable 'var' might not have been initialized
I thought all variables or references were initialized to null. Why do you need to do:
String var = null;
??
Instance and class variables are initialized to null (or 0), but local variables are not.
See §4.12.5 of the JLS for a very detailed explanation which says basically the same thing:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created:
[snipped out list of all default values]
Each method parameter is initialized to the corresponding argument value provided by the invoker of the method.
Each constructor parameter is initialized to the corresponding argument value provided by a class instance creation expression or explicit constructor invocation.
An exception-handler parameter is initialized to the thrown object representing the exception.
A local variable must be explicitly given a value before it is used, by either initialization or assignment, in a way that can be verified by the compiler using the rules for definite assignment.
It's because Java is being very helpful (as much as possible).
It will use this same logic to catch some very interesting edge-cases that you might have missed. For instance:
int x;
if(cond2)
x=2;
else if(cond3)
x=3;
System.out.println("X was:"+x);
This will fail because there was an else case that wasn't specified. The fact is, an else case here should absolutely be specified, even if it's just an error (The same is true of a default: condition in a switch statement).
What you should take away from this, interestingly enough, is don't ever initialize your local variables until you figure out that you actually have to do so. If you are in the habit of always saying "int x=0;" you will prevent this fantastic "bad logic" detector from functioning. This error has saved me time more than once.
Ditto on Bill K. I add:
The Java compiler can protect you from hurting yourself by failing to set a variable before using it within a function. Thus it explicitly does NOT set a default value, as Bill K describes.
But when it comes to class variables, it would be very difficult for the compiler to do this for you. A class variable could be set by any function in the class. It would be very difficult for the compiler to determine all possible orders in which functions might be called. At the very least it would have to analyze all the classes in the system that call any function in this class. It might well have to examine the contents of any data files or database and somehow predict what inputs users will make. At best the task would be extremely complex, at worst impossible. So for class variables, it makes sense to provide a reliable default. That default is, basically, to fill the field with bits of zero, so you get null for references, zero for integers, false for booleans, etc.
As Bill says, you should definitely NOT get in the habit of automatically initializing variables when you declare them. Only initialize variables at declaration time if this really make sense in the context of your program. Like, if 99% of the time you want x to be 42, but inside some IF condition you might discover that this is a special case and x should be 666, then fine, start out with "int x=42;" and inside the IF override this. But in the more normal case, where you figure out the value based on whatever conditions, don't initialize to an arbitrary number. Just fill it with the calculated value. Then if you make a logic error and fail to set a value under some combination of conditions, the compiler can tell you that you screwed up rather than the user.
PS I've seen a lot of lame programs that say things like:
HashMap myMap=new HashMap();
myMap=getBunchOfData();
Why create an object to initialize the variable when you know you are promptly going to throw this object away a millisecond later? That's just a waste of time.
Edit
To take a trivial example, suppose you wrote this:
int foo;
if (bar<0)
foo=1;
else if (bar>0)
foo=2;
processSomething(foo);
This will throw an error at compile time, because the compiler will notice that when bar==0, you never set foo, but then you try to use it.
But if you initialize foo to a dummy value, like
int foo=0;
if (bar<0)
foo=1;
else if (bar>0)
foo=2;
processSomething(foo);
Then the compiler will see that no matter what the value of bar, foo gets set to something, so it will not produce an error. If what you really want is for foo to be 0 when bar is 0, then this is fine. But if what really happened is that you meant one of the tests to be <= or >= or you meant to include a final else for when bar==0, then you've tricked the compiler into failing to detect your error. And by the way, that's way I think such a construct is poor coding style: Not only can the compiler not be sure what you intended, but neither can a future maintenance programmer.
I like Bill K's point about letting the compiler work for you- I had fallen into initializing every automatic variable because it 'seemed like the Java thing to do'. I'd failed to understand that class variables (ie persistent things that constructors worry about) and automatic variables (some counter, etc) are different, even though EVERYTHING is a class in Java.
So I went back and removed the initialization I'd be using, for example
List <Thing> somethings = new List<Thing>();
somethings.add(somethingElse); // <--- this is completely unnecessary
Nice. I'd been getting a compiler warning for
List<Thing> somethings = new List();
and I'd thought the problem was lack of initialization. WRONG. The problem was I hadn't understood the rules and I needed the <Thing> identified in the "new", not any actual items of type <Thing> created.
(Next I need to learn how to put literal less-than and greater-than signs into HTML!)
I don't know the logic behind it, but local variables are not initialized to null. I guess to make your life easy. They could have done it with class variables if it were possible. It doesn't mean you have to have it initialized in the beginning. This is fine :
MyClass cls;
if (condition) {
cls = something;
else
cls = something_else;
Sure, if you've really got two lines on top of each other as you show- declare it, fill it, no need for a default constructor. But, for example, if you want to declare something once and use it several or many times, the default constructor or null declaration is relevant. Or is the pointer to an object so lightweight that its better to allocate it over and over inside a loop, because the allocation of the pointer is so much less than the instantiation of the object? (Presumably there's a valid reason for a new object at each step of the loop).
Bill IV

Categories

Resources