Can a class be nullified from within the class itself? - java

For example, is this code valid?.
class abc{
int x,y;
abc(int x,int y){
this.x=x;
this.y=y;
while(true)
update();
}
public void update(){
x--;
y--;
if(y==0)
this=null;
}
}
If the above is not valid, then please explain why. I am in need of a class that after certain iterations ceases to exist. Please suggest alternatives to the above approach.

No, this code is not valid.
Furthermore, I don't see what meaningful semantics it could have had if it were valid.
Please suggest alternatives to the above approach.
The object exists for as long as there are references to it. To make the object eligible for garbage collection you simply need to ensure that there are no references pointing to it (in your case, this should happen as soon as y reaches zero).

No. The reason is that you do not make object null. When you say obj = null; You just put null to variable that previously hold reference to object. There are probably a lot of other references to the same object.
I think that what you want to do is to kind of invalidate object and make it garbage collected but take this decision inside the class. If this is the problem I'd recommend you to take a look on weak references.
Other possible solution is to implement kind of "smart reference" in java. You can create your class SmartReference that will hold the real reference to the object. The object should hold callback to this smart reference and call its method invalidate() that is something like your syntactically wrong expression this = null. You have to care not to refer to such objects directly but only via smart reference.
The only question is "why do you want to do this?". Really, this will cause the code to be more complicated and unstable. Imagine: the object decides to invalidate itself, so the reference that "smart reference" is holding becomes null. Now all holders of this smart reference will get NPE when trying to use the object! This is exactly the reason the such mechanism does not exist in java and that application programmer cannot mange the memory directly.
Bottom line: remove all object references and let GC to do its hard job. Trust it. It knows to clean the garbage.

I think this is a good question.
I've had loads of cases where I'd like Objects to validate themselves after/during construction and if it finds reason to, to just return an empty value or go back up the stack and skip over creating that object.
Mostly in the case of where you are creating a list of objects from a list of other values. If a value is garbage and you want your object to recognise this.
Rather then have to code a function outside the Class itself to validate the creation, it would be much neater to allow the object to do it.
It's a shame java doesn't allow for things like this on the assumption the programmer is probably going to mess it up. If you code well it would be a nice feature.

I think you need to rethink why you want to do this, because what you're suggesting doesn't even exist as a concept in Java.
The this variable always refers to the object itself. You can't "nullify" an object, only a reference (since after all, what you're doing is assigning a reference to point to null instead of its previous object). It wouldn't make sense to do that with this, as it's always a pointer to the current object in scope.
Are you trying to force an object to be destroyed/garbage collected? If so, you can't do that while other parts of your code still have references to it (and if they don't have references, it will be garbage collected anyway).
What did you hope/think this would do, anyway?

your code must be get compile time error..
Coz..
The left-hand side of an assignment must be a variable
this is not a variable its a keyword..
this=null;

Related

Passing big objects references instead of small objects to methods have any differences in processing or memory consumption?

I have a coding dilemma, and I don't know if there's a pattern or practice that deals with it. Whenever I have to pass some values to a method, most times I try to pass only the needed objects, instead of passing the objects which are being composed by them.
I was discussing with a friend about how Java manages heap and memory stuff and we didn't get anywhere.
Let me give two examples:
//Example 1:
private void method doSomething(String s, Car car, boolean isReal){...}
...
String s = myBigObject.getLabels.getMainName();
Car car = myBigObject.getCar();
boolean isReal = myBigObject.isRealCar();
doSomething(s, car, isReal);
//Example 2 - having in mind that BigObject is a really big object and I'll only use those 3 atributes:
private void method doSomething(BigObject bigObject){...}
...
doSomething(myBigObject);
In the 2nd example, it seems to me memory will be kind of wasted, passing a big object without really needing it.
Since Java passes only references to objects (and copies them, making it technically pass-by-value), there is no memory overhead for passing "big objects". Your Example 1 actually uses a little more memory.
However, there may still be good reason to do it that way: it removes a dependency and allows you to call doSomething on data that is not part of a BigObject. This may or may not be an advantage. If it gets called a lot with BigObject parameters, you'd have a lot of duplicate code extracting those values, which would not be good.
Note also that you don't have to assign return values to a local variable to pass them. You can also do it like this:
doSomething(myBigObject.getLabels().getMainName(),
myBigObject.getCar(),
myBigObject.isRealCar());
You're already only passing a reference to BigObject, not a full copy of BigObject. Java passes references by value.
Arguably, you're spending more memory the first way, not less, since you're now passing two references and a boolean instead of a single reference.
Java uses pass by value, when ever we pass an object to a method keep in mind that we are not going to pass all the values store in side the object we just pass the bits( some thing like this ab06789c) which is the value of the address on which the object is stored in memory(Heap Memory). So you are wasting more memory in first case rather than the 2nd one. Refer to JAVA pass-by-reference or pass-by-memory
All references are the same size, so how could it use more memory? It doesn't.

Most efficient way to pass a Java object around?

I'm considering creating the following method:
public static MyBigCollection doSomeStuff(MyBigCollection m) { ... return m; }
and then in another method (perhaps in another class), using it like so:
MyBigCollection mbc = new MyBigCollection();
mbc = stuffClass.doSomeStuff(mbc);
Am I going about this the right way -- is this an efficient way to "do some stuff" to an object? I'd like to break off the stuff like so for extensibility. I've been doing c# for so long I'm just not sure with java. In c# the method could return void and I can simply call doSomeStuff(mbc) -- which would effectively pass my object by reference and do some stuff to it. I've been reading that java works differently so I wanted to check with the experts here.
I'd refactor to:
stuffClass.doSomeStuff(mbc);
(i.e., a method that modifies mbc and returns void)
Keep in mind that all Java Objects are stored in heap memory, and passed around with reference pointers.
The way you're doing it is fine, but you don't actually need to return the object at the end of the method. As such, the following would be simpler...
MyBigCollection mbc = new MyBigCollection();
stuffClass.doSomeStuff(mbc);
Objects in Java are passed by reference, so any modification on the mbc Object in the doSomeStuff() method would still be retained in the mbc variable after the end of the method call.
The only reason why you might consider returning the mbc Object is if you want the ability to join multiple methods together, such as this...
MyBigCollection mbc = new MyBigCollection();
mbc.doStuff1().doStuff2().doStuff3();
In this case, because mbc is returned by each of the doStuff() methods, the next method can be called straight back on to the same Object. Without returning the reference, you'd have to do something like this instead...
MyBigCollection mbc = new MyBigCollection();
mbc.doStuff1();
mbc.doStuff2();
mbc.doStuff3();
Which is the same thing, but not quite as compact. How you go about it really depends on how you intend to use the methods and the Object itself.
There's only one way to pass Java objects around. Java passes everything by value. Objects aren't passed; they live on the heap. You pass references around, not objects.
Same as C#, as far as I know.
This kind of micro-optimization is usually meaningless.
I think your question is around how Java passes references to objects. Java passes by value, which can be confusing when first said. For objects, this means that the value of the reference to the object is passed to the method. Interacting with the object referred to by the value will alter the object 'passed in', so you don't need to return it.
Strings are treated differently as they are immutable. Primitives are also pass by value, but as the value passed is not a reference, you will not alter the original variable.
The easiest way to test this is to write some code and observe (you might also consider the Java tutorials)

Is it a good practice to change arguments in Java

Suppose I am writing a method foo(int i) in Java.
Since i is passed by value it is safe to change it in foo. For example
void foo(int i) {
i = i + 1; // change i
...
}
Is it considered good or bad practice to change arguments of methods in Java?
It's considered bad practice in general, though some people overlook it as you can see in the other answers.
For parameters like primitives that are directly passed in by value, there is no advantage in overriding the original variable. In this case you should make a copy as suggested by #João.
For parameters whose reference is passed in by value (objects), if you modify the handle to point to a different object, that is downright confusing. It's all the more important because modifying the contents of an object passed as a parameter will modify the original object too.
If you replace the object referred to by the handle, and then modify its contents, the object referred to by the original reference in the caller will not be replaced, but someone reading the code might expect it to be.
Whereas if you don't replace the object, and modify the contents, the method calling your method might not expect this change. This category generally comes under security-related bad practices.
It's merely a personal opinion, but I think it can be confusing for other people that may want to use the original parameter value later in that code, and may not notice that it has already been changed.
Plus, it's cheap to simply create another variable and assign it the modified value (i.e., int j = i + 1).
Since i is passed by value it is safe to change it foo()
It is absolutely safe even when you pass an object reference because they are local: i.e., assigning a new reference to the local reference will not have any impact on the original reference in the calling code
It's your personal choice. However i would not change the argument values as one might loose the track of the actual value passed in to this method.
What is important to note is that i = i + 1; does not really change i. It only changes your local copy of i (in other words, the i in the calling code won't change).
Based on that, it is a matter of readability and avoiding unexpected behaviour in your code by complying with the POLS (Principle Of Least Surprise).
Neutral. But it would be considered a better practice by many people to change the method to:
void foo(final int i) {
int j = i + 1; // not change i
...
}
Feel free to work either way.
Depends on context. I lean towards "bad practice", for two reasons:
Some people may think the original value is being changed.
It may make the code harder to reason about (mitigated with appropriately-short methods).
A third issue pops up when it's a reference value. If you modify the parameter reference to point at something else and change its state, the original won't be modified–this may or may not be what's intended. If you create another reference to the parameter and change the new reference's state, the parameter's reference will be changed–which also may or may not be what's intended.

Assigning "null" to objects in every application after their use

Do you always assign null to an object after its scope has been reached?
Or do you rely on the JVM for garbage collection?
Do you do it for all sort of applications regardless of their length?
If so, is it always a good practice?
It's not necessary to explicitly mark objects as null unless you have a very specific reason. Furthermore, I've never seen an application that marks all objects as null when they are no longer needed. The main benefit of garbage collection is the intrinsic memory management.
no, don't do that, except for specific cases such as static fields or when you know a variable/field lives a lot longer than the code referencing it
yes, but with a working knowledge of your VM's limits (and how to cause blocks of memory to be held accidentally)
n/a
I declare almost all of my variables as "final". I also make my methods small and declare most variables local to methods.
Since they are final I cannot assign them null after use... but that is fine since the methods are small the objects are eligible for garbage collection once they return. Since most of the variables are local there is less chance of accidentally holding onto a reference for longer than needed (memory leak).
Assignin null to a variable does not implicitly mean it will be garbage collected right away. In fact it most likely won't be. Whether you practice setting variables to null is usually only cosmetic (with the exception of static variables)
We don't practice this assigning "null". If a variable's scope has reached it's end it should already be ready for GC. There may be some edge cases in which the scope lasts for a while longer due to a long running operation in which case it might make sense to set it to null, but I would imagine they would be rare.
It also goes without saying that if the variable is an object's member variable or a static variable and hence never really goes out of scope then setting it to null to GC is mandatory.
Garbage collection is not as magical as you might expect. As long as an object is referenced from any reachable object it simply can't be collected. So it might be absolutely necessary to null a reference in order to avoid memory leaks. I don't say you should do this always, but always when it's necessary.
As the others have mentioned, it's not usually necessary.
Not only that, but it clutters up your code and increases the data someone needs to read and understand when revisiting your code.
Assigning is not done to objects, it is done to variables, and it means that this variable then holds a reference to some object. Assigning NULL to a variable is not a way to destroy an object, it just clears one reference. If the variable you are clearing will leave its scope afterwards anyway, assigning NULL is just useless noise, because that happens on leaving scope in any case.
The one time I tend to use this practice is if I need to transform a large Collection in some early part of a method.
For example:
public void foo() {
List<? extends Trade> trades = loadTrades();
Map<Date, List<? extends Trade>> tradesByDate = groupTradesByDate(trades);
trades = null; // trades no longer required.
// Apply business logic to tradesByDate map.
}
Obviously I could reduce the need for this by refactoring this into another method: Map<Date, List<? extends Trade>>> loadTradesAndGroupByDate() so it really depends on circumstances / clarity of code.
I only assign a reference to null when:
The code really lies in a memory-critical part.
The reference has a wide scope (and must be reused later). If it is not the case I just declare it in the smallest possible code block. It will be available for collection automatically.
That means that I only use this technique in iterative process where I use the reference to store incoming huge collection of objects. After processing, I do not need the collection any more but I want to reuse the reference for the next collection.
In that case (and only in that case), I then call System.gc() to give a hint to the Garbage Collector. I monitored this technique through heap visualizer and it works very well for big collections (more then 500Mb of data).
When using the .Net I don't think there's a need to set the object to null. Just let the garbage collection happen.
- Do you always assign null to an object after its scope has been reached?
No
- Or do you rely on the JVM for garbage collection?
Yes
- Do you do it for all sort of applications regardless of their length?
Yes
- If so, is it always a good practice?
N/A
I assume you're asking this question because you've seen code with variables being assigned to null at the point where they will never be accessed again.
I dislike this style, but another programmer used it extensively, and said he was taught to do so at a programming course at his university. The reasoning he gave is that it would prevent undetectable bugs if he tried to reuse the variable later on, instead of indeterminate behavior, he'd get a null pointer exception.
So if you're prone to using variables where you shouldn't be using variables, it might make your code more easy to debug.
There was a class of memory leak bugs that happened regardless of whether I set the reference to null - if the library I was using was written in a language like C without memory management, then simply setting the object to null would not necessarily free the memory. We had to call the object's close() method to release the memory (which, of course, we couldn't do after setting it to null.)
It thus seems to me that the de facto method of memory management in java is to rely on the garbage collector unless the object/library you're using has a close() method (or something similar.)

Does setting Java objects to null do anything anymore?

I was browsing some old books and found a copy of "Practical Java" by Peter Hagger. In the performance section, there is a recommendation to set object references to null when no longer needed.
In Java, does setting object references to null improve performance or garbage collection efficiency? If so, in what cases is this an issue? Container classes? Object composition? Anonymous inner classes?
I see this in code pretty often. Is this now obsolete programming advice or is it still useful?
It depends a bit on when you were thinking of nulling the reference.
If you have an object chain A->B->C, then once A is not reachable, A, B and C will all be eligible for garbage collection (assuming nothing else is referring to either B or C). There's no need, and never has been any need, to explicitly set references A->B or B->C to null, for example.
Apart from that, most of the time the issue doesn't really arise, because in reality you're dealing with objects in collections. You should generally always be thinking of removing objects from lists, maps etc by calling the appropiate remove() method.
The case where there used to be some advice to set references to null was specifically in a long scope where a memory-intensive object ceased to be used partway through the scope. For example:
{
BigObject obj = ...
doSomethingWith(obj);
obj = null; <-- explicitly set to null
doSomethingElse();
}
The rationale here was that because obj is still in scope, then without the explicit nulling of the reference, it does not become garbage collectable until after the doSomethingElse() method completes. And this is the advice that probably no longer holds on modern JVMs: it turns out that the JIT compiler can work out at what point a given local object reference is no longer used.
No, it's not obsolete advice. Dangling references are still a problem, especially if you're, say, implementing an expandable array container (ArrayList or the like) using a pre-allocated array. Elements beyond the "logical" size of the list should be nulled out, or else they won't be freed.
See Effective Java 2nd ed, Item 6: Eliminate Obsolete Object References.
Instance fields, array elements
If there is a reference to an object, it cannot be garbage collected. Especially if that object (and the whole graph behind it) is big, there is only one reference that is stopping garbage collection, and that reference is not really needed anymore, that is an unfortunate situation.
Pathological cases are the object that retains an unnessary instance to the whole XML DOM tree that was used to configure it, the MBean that was not unregistered, or the single reference to an object from an undeployed web application that prevents a whole classloader from being unloaded.
So unless you are sure that the object that holds the reference itself will be garbage collected anyway (or even then), you should null out everything that you no longer need.
Scoped variables:
If you are considering setting a local variable to null before the end of its scope , so that it can be reclaimed by the garbage collector and to mark it as "unusable from now on", you should consider putting it in a more limited scope instead.
{
BigObject obj = ...
doSomethingWith(obj);
obj = null; // <-- explicitly set to null
doSomethingElse();
}
becomes
{
{
BigObject obj = ...
doSomethingWith(obj);
} // <-- obj goes out of scope
doSomethingElse();
}
Long, flat scopes are generally bad for legibility of the code, too. Introducing private methods to break things up just for that purpose is not unheard of, too.
In memory restrictive environments (e.g. cellphones) this can be useful. By setting null, the objetc don't need to wait the variable to get out of scope to be gc'd.
For the everyday programming, however, this shouldn't be the rule, except in special cases like the one Chris Jester-Young cited.
Firstly, It does not mean anything that you are setting a object to null. I explain it below:
List list1 = new ArrayList();
List list2 = list1;
In above code segment we are creating the object reference variable name list1 of ArrayList object that is stored in the memory. So list1 is referring that object and it nothing more than a variable. And in the second line of code we are copying the reference of list1 to list2. So now going back to your question if I do:
list1 = null;
that means list1 is no longer referring any object that is stored in the memory so list2 will also having nothing to refer. So if you check the size of list2:
list2.size(); //it gives you 0
So here the concept of garbage collector arrives which says «you nothing to worry about freeing the memory that is hold by the object, I will do that when I find that it will no longer used in program and JVM will manage me.»
I hope it clear the concept.
One of the reasons to do so is to eliminate obsolete object references.
You can read the text here.

Categories