I´m new in Java and I want to know if is necessary to dispose object to free memory when I serialize it? I try to use my serializable object after the serialization and works fine but my goal is don´t get access until desserealize it. Thanks.
Poo p = new Poo();
try {
FileOutputStream g = new FileOutputStream("obj.ser");
ObjectOutputStream stream = new ObjectOutputStream(g);
stream.writeObject(p);
stream.close();
}
catch(Exception e) { e.printStackTrace(); }
p.getInfo(); // works
You can use methods that customize serialisation to invalidate the object (i.e. make the object throw an exception on every call of a non-private method; That way you at least ensure no methods are sucessfully called).
public final class Poo implements Serializable {
private volatile boolean invalid = false;
public String getInfo() {
synchronized (this) {
if (invalid) {
throw new IllegalStateException("Object shouldn't be used until deserialized");
}
}
// do something
}
// do the same to other methods
// if necessary Object methods like equals and hashCode too
private class SerializationProxy implements Serializable {
private Object readResolve() {
Poo.this.invalid = false;
return Poo.this;
}
}
private synchronized Object writeReplace() {
invalid = true;
return new SerializationProxy();
}
}
However if you just want to make the memory avaliable, it suffices to set all references to the object to null. E.g. If there are no static references to p:
p = null;
Which is automatically done at the end of the scope were you declare p (most likely end of the method). Maybe the compiler can even do some optimisation (release object if no longer needed); however I don't know, if the language spec allows this.
EDIT
Made Poo final to prevent inherited classes from overriding & adding methods and ignore the invalid field.
The answer is no, it is not always necessary to "dispose" of an object after serializing it.
If you have a specific reason for "disposing" of the object (whatever that means in the context of your code), then do so. If you have a question about this specific reason, then improve your question, but your question asks in a general sense, and again, in that sense the answer is no.
Serialization is generation of some bytes based on an object in memory. You can do something with these bytes like write them to a file, send them over the network, etc. The original object remains the same.
Disposing of an object to "free up memory" is performed by the garbage collector automatically sometime after the object is no longer accessible to your program. The best you can do is make sure you are not holding any reference to the object. It will then be collected.
These are separate and unrelated concepts.
Related
If an object reference is passed to a method, is it possible to make the object "Read Only" to the method?
Not strictly speaking. That is, a reference that can mutate an object can not be turned into a reference that can not mutate an object. Also, there is not way to express that a type is immutable or mutable, other than using conventions.
The only feature that ensure some form of immutability would be final fields - once written they can not be modified.
That said, there are ways to design classes so that unwanted mutation are prevented. Here are some techniques:
Defensive Copying. Pass a copy of the object, so that if it is mutated it doesn't break your internal invariants.
Use access modifiers and/or interface to expose only read-only methods. You can use access modifieres (public/private/protected), possibly combined with interface, so that only certain methods are visible to the other object. If the methods that are exposed are read-only by nature, you are safe.
Make your object immutable by default. Any operation on the object returns actually a copy of the object.
Also, note that the API in the SDK have sometimes methods that return an immutable version of an object, e.g. Collections.unmodifiableList. An attempt to mutate an immutable list will throw an exception. This does not enforce immutability statically (at compile-time with the static type system), but is is a cheap and effective way to enforce it dynamically (at run-time).
There has been many research proposals of Java extension to better control of aliasing, and accessibility. For instance, addition of a readonly keyword. None of them is as far as I know planned for inclusion in future version of Java. You can have a look at these pointers if you're interested:
Why We Should Not Add ''Read-Only'' to Java (yet) -- it lists and compare most of the proposals
The Checker Framework: Custom pluggable types for Java -- a non intrusive way to extend the type system, notably with immutable types.
The Checker Framework is very interesting. In the Checker Framework, look at Generic Universe Types checker, IGJ immutability checker, and Javari immutability checker. The framework works using annotations, so it is not intrusive.
No, not without decorating, compositing, cloning, etc.
There's no general mechanism for that. You'll need to write special-case code to achieve it, like writing an immutable wrapper (see Collections.unmodifiableList).
You could achieve a similar thing in most cases by cloning the Object as the first statement of the method, such as this...
public void readOnlyMethod(Object test){
test = test.clone();
// other code here
}
So if you called readOnlyMethod() and pass in any Object, a clone of the Object will be taken. The clone uses the same name as the parameter of the method, so there's no risk of accidentally changing the original Object.
No. But you could try to clone the object before passing it, so any changes made by the method won't affect the original object.
making it implement a interface which has only read only methods (no setter methods) this gives a copy of an object (road-only copy) and returning the read only instance of interface instead of returning the instance of an object itself
You could define all parameters of the objects as final but that makes the object read only to everyone.
I believe your real question is about avoiding escape references.
As pointed out in some answers to extract an Interface from class and expose only get methods. It will prevent modification by accident but it is again not a foolproof solution to avoid above problem.
Consider below example:
Customer.java:
public class Customer implements CustomerReadOnly {
private String name;
private ArrayList<String> list;
public Customer(String name) {
this.name=name;
this.list = new ArrayList<>();
this.list.add("First");
this.list.add("Second");
}
#Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public ArrayList<String> getList() {
return list;
}
public void setList(ArrayList<String> list) {
this.list = list;
}
}
CustomerReadOnly.java:
public interface CustomerReadOnly {
String getName();
ArrayList<String> getList();
}
Main.java:
public class Test {
public static void main(String[] args) {
CustomerReadOnly c1 = new Customer("John");
System.out.println("printing list of class before modification");
for(String s : c1.getList()) {
System.out.println(s);
}
ArrayList<String> list = c1.getList();
list.set(0, "Not first");
System.out.println("printing list created here");
for(String s : list) {
System.out.println(s);
}
System.out.println("printing list of class after modification");
for(String s : c1.getList()) {
System.out.println(s);
}
}
}
Ouput:
printing list of class before modification
First
Second
printing list created here
Not first
Second
printing list of class after modification
Not first
Second
So, as you can see extracting interface and exposing only get methods works only if you don't have any mutable member variable.
If you have a collection as a member variable whose reference you don't want to get escape from class, you can use Collections.unmodifiableList() as pointed out in ewernli's answer.
With this no external code can modify the underlying collection and your data is fully read only.
But again when it comes to custom objects for doing the same, I am aware of the Interface method only as well which can prevent modification by accident but not sure about the foolproof way to avoid reference escape.
Depending on where you want the rule enforced. If you are working collaboratively on a project, use final with a comment telling the next person they are not meant to modify this value. Otherwise wouldn't you simply write the method to not touch the object?
public static void main(String[] args) {
cantTouchThis("Cant touch this");
}
/**
*
* #param value - break it down
*/
public static void cantTouchThis(final String value) {
System.out.println("Value: " + value);
value = "Nah nah nah nah"; //Compile time error
}
So specifically to this method, the value will never be written to, and it is enforced at compile time making the solution extremely robust. Outside the scope of this method, the object remains unaltered without having to create any sort of wrapper.
private boolean isExecuteWriteQueue = false;
public boolean isWriting(){
final boolean b = isExecuteWriteQueue;
return b;
}
Expanding on ewernli's answer...
If you own the classes, you can use read-only interfaces so that methods using a read-only reference of the object can only get read-only copies of the children; while the main class returns the writable versions.
example
public interface ReadOnlyA {
public ReadOnlyA getA();
}
public class A implements ReadOnlyA {
#Override
public A getA() {
return this;
}
public static void main(String[] cheese) {
ReadOnlyA test= new A();
ReadOnlyA b1 = test.getA();
A b2 = test.getA(); //compile error
}
}
If you don't own the classes, you could extend the class, overriding the setters to throw an error or no-op, and use separate setters. This would effectively make the base class reference the read-only one, however this can easily lead to confusion and hard to understand bugs, so make sure it is well documented.
I would like to kill/delete an object from inside of the object itself.
What I need is, for the reference to this object to be null, but I don't want to pass handle to the container. Here is a little code example:
class Obj {
void run(){
if(true)
kill();
}
}
class A{
Obj o;
void main(){
o.run();
}
}
After running o.run() i would like to o == null. Is this possible?
You can't null references to an object from within the object itself, as you want. Here is how you can do it, from the point where you actually have the reference you want to nullify, in scope.
Null the reference once run() has completed:
Edit Based on feedback...
class Obj {
private boolean killMe = false;
void run(){
if(someConditionHere) {
killMe = true;
}
}
public boolean isKillable() { return killMe; }
}
class A{
Obj o;
void main(){
o.run();
if(o.isKillable()) {
o = null;
}
}
}
You won't be able to nullify an object reference from its own member method because an object cannot change references owned by other objects. But you can set all its members field to null: future callers will certainly get a NullPointerException every time they try to access the object. It's even better than suicide if you think about it: the object will stay just alive enough to spread death around him.
If you're lucky you could even get the entire application to kill itself!
The object world would be an awful mess if an object could set all references other objects have already made to it to null, because in OOP an object "owns" its properties (private ones anyway) and being able to have them changed from an external source would completely break the encapsulation concept.
Now I am pretty sure it may be handy sometimes (else you wouldn't have asked this question) but if you are programming in java you won't be allowed to do that "out of the box".
The only way is to make your object and the objects holding reference to it agreeing on a common strategy.
Like an isDead method that they should call before trying to do anything else.
You can also implement a PsychologicalSupport object that will proxy access from external objects to your depressive one. When your object wants to die, he just has to notify its Support object about it, and the PS object will stop proxying message, and your object will be garbage collected.
I would do this:
class Obj {
Obj run(){
if(someConditionHere) {
return null;
}
return this;
}
}
class A {
Obj o;
void main(){
o = o.run();
}
}
So there is no need to check for o's internal state in A. And it is more encapsulated.
In Java, every class implicitly extends the Object class. So, does this mean we can create an object of the Object class ?
public static void main(String[] args) {
Object ob=new Object();
// code here ....
}
When I tried it, it compiled and ran successfully. In that case, can someone please explain when do we generally create an object of the Object class ?
You could instantiate an instance of an Object if you want to do a synchronization lock.
public void SomeClass {
private Object lock = new Object();
private SomeState state;
public void mutateSomeSharedState() {
synchronized(lock) {
//mutate some state
}
}
public SomeState readState() {
synchronized(lock) {
//access state
}
}
}
It might be necessary to do this when this is already used to lock some other state of the same object, or if you want to have your lock be private (ie, no one else can utilize it). Even if it isn't necessary, some people prefer to do things that way. This is merely an example of when someone might do it.
Normally we don't create an object of the Object class directly. Usually, we create instances of direct/indirect subclasses of Object.
A scenario where we create an instance of Object is to create an object to synchronize threads.
Eg:
Object lock = new Object();
//...
synchronize( lock ) {
//...
//...
}
However the Object class is used a lot to describe parameters of methods and of instance variables that may assume values of different classes (polymorphism).
Eg:
void example(Object arg) {
// ...
System.out.println( "example=" + arg.toString() );
}
Object foo = returnObject();
Sometimes the use of Generics may be better than using Object to describe parameters and variables.
For the most part I believe Object is no longer used explicitly.
Since Java's debut of Generics, casting to the Object class is almost non-existent.
Since java.lang.Object is the super most class, it can be substituted with any instance we create. This concept is very useful when you not aware of the type( eg: A method which conditionally returns different types , Collections with multiple types)
Also commonly used when you want to instantiate class from String,or execute a method using reflections.
However, direct usage of Object is getting redundant due to Generics.
Cheers
Satheesh
I was looking at these two implementations of the Singleton Pattern:
Class Customer {
int x;
static int count = 0;
private Customer()
{
x = 1;
}
public static Customer GetCustomer()
{
if(count==0)
{
count++;
return new Customer();
}
else
{
return null;
}
}
}
Implementation 1 in which the constructor is not called if the class is already instantiated once. OR
Class Customer{
int x;
static int count = 0;
public Customer()
{
if(count == 0)
{
x = 1;
count++;
}
else
{
return;
}
}
Implementation 2 in which the constructor is called irrespective of weather the class is already instantiated once or not. I watched a video lecture online that says Implementation 2 is not preferred as it allocates memory for the constructor although the object is not instantiated for the second time. I am aware Java has automatic Garbage Collection, but just wanted to know if what I watched in the video lecture is relevant.
There are some that would say that no implementation of a singleton is the correct one, but I'm not quite in that camp.
People often tend to use them badly (as a God object, for example) but they still have their place (in my opinion, which has little to do with this answer).
For the purposes of this answer, I'm going to assume you've made the right decision in needing a singleton, but I do urge you to read up on its potential problems - there may well be a better way to achieve your ends.
Having said that, I'm not sure if your code samples are correct anyway. A singleton is supposed to return one and only one instance, creating one if necessary, giving you the previously created one if not.
I fail to see how your first code sample honors that contract. It'll give you a new one the first time it's called, then it will give you nothing after that.
And your second code sample doesn't seem to prevent multiple objects at all.
So I'd be thinking very carefully about whether you want to continue watching that video, if this is the quality of the education they deliver.
In any case, I prefer the one that only constructs once, since you're only supposed to have one object of that class. In other words, a static getMe() call that is properly synchronised to prevent race conditions allowing creation of more than one Me object, and that creates a new object the first time, returning that same object on subsequent calls.
In pseudo-code, that would be something like:
class Me {
private Me() {};
private static Me *loner = NULL;
public static synchronised Me *getMe() {
if loner == NULL
loner = new Me();
return loner;
}
}
Writing a correct singleton is not that easy. You need to take care of race conditions and to defend against reflection attacks. For example a private constructor might be invoked via reflection to create one more instance of an object. The easiest and safest singleton implementation in java is done with an enum:
enum Singleton {
INSTANCE;
}
That's because enum constants are spedified by JLS to be singletons (section 8.9 of JLS):
An enum type has no instances other than those defined by its enum constants.
I have extended a class in Java that has a private variable that I want to get the value of before it is changed. There are no methods to access this variable in the super class. I have tried super().m_zoomArea (the variable is in the ZoomableChart class of jChart2D). The variable is updated when the mouseDragged method is called. I have overridden this method and would like to get the value of the variable before it is updated.
You can access private variable of any class, but it's a bad idea, because you're breaking one of the basic principles of OOP - encapsulation.
But sometimes programmer are forced to break it. Here is the code, which solves your problem:
Extended class
public class ExtZoomableChart
extends ZoomableChart {
public Rectangle2D getZoomArea() {
try {
Field field = ZoomableChart.class.getDeclaredField("m_zoomArea");
field.setAccessible(true);
Object value = field.get(this);
field.setAccessible(false);
if (value == null) {
return null;
} else if (Rectangle2D.class.isAssignableFrom(value.getClass())) {
return (Rectangle2D) value;
}
throw new RuntimeException("Wrong value");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
and call example:
public class Main {
public static void main(String[] args) {
ExtZoomableChart extZoomableChart = new ExtZoomableChart();
Rectangle2D d = extZoomableChart.getZoomArea();
System.out.println(d);
}
}
You don't need to extend ZoomableChart to get private variable. You can get it value almost from everywhere. But remember - usually it's a bad practice.
You can't. The whole point of it being private is that you can't get at the variable. If the class hasn't given any way of finding it out, you can't get it. That may or may not be a design flaw in the class, but unless you use reflection with suitable privileges (which I don't recommend - you're basically relying on private implementation details) you're going to have to think of an alternative approach.
You could use reflection but it's a bad idea. A private field is private because the developer doesn't want you to mess with it.
I won't give you the way to do it here, but if you really know what you do, follow the links below at your own risks. Again, you shouldn't even think about doing this.
On the same topic :
Does reflection breaks the idea of private methods, because private methods can be access outside of the class?
Accessing private variables in Java via reflection
Is it possible in Java to access private fields via reflection
You can't access private variables from outside of the class. In order to access it you would have to have it be protected.
You can do this with the Reflection API (Specifically, see the setAccessible() method). Anyway, this is a hack and may not work if there is a SecurityManager installed in the VM.