I need to pass java.lang.reflect.Field from one process to another using RMI, but Field does not implement Serializable interface. how can I overcome this problem?
It doesn't make sense to pass a Field via RMI. A Field instance is really a dependent object of a java.lang.Class instance, and Class objects are not transmissible either. (And the reason that a Class is not transmissible is that it would present all sorts of nasty type checking problems ... considering that a Class instance actually denotes a reference type.)
You will need to declare the relevant Field field as transient. If you want to transmit the Field information, you are probably going to need to pass it in the form of a field name / class name, and then reconstruct the Field at the other end in a custom readObject method.
Related
I have a class that is serialised. Now I need to add a new variable into the class, with setter and getter methods. This class is sent over wire in RMI.
Without changing the UID, can I add new parameters and getter and setter methods for it? I tried to write an example class that is sent over wire, and did not change the UID, and added new parameters and getter and setter methods for it. On the other end, I tested it and I still got the values properly. I had assumed, if I add new parameters, getter and setter methods, I need to change the UID. Am I wrong?
If you hard-code the SerialVersionUID of a class, (to 1L, usually), store some instances, and then re-define the class, you basically get this behavior (which is more or less common sense):
New fields (present in class definition, not present in the serialized instance) are assigned a default value, which is null for objects, or the same value as an uninitialized field for primitives.
Removed fields (not present in class definition but present in the serialized instance) are simply ignored.
So the general rule of thumb is, if you simply add fields and methods, and don't change any of the existing stuff, AND if you're OK with default values for these new fields, you're generally OK.
Wow, a lot of bad information.
Java serialization is +very+ robust. There are a very well defined set of rules governing backwards compatibility of objects with the same uid and different data. the basic idea is that as long as you don't change the the type of an existing member, you can maintain the same uid without data issues.
that said, your code still needs to be smart about handling classes with potentially missing data. the object may deserialize correctly, but there may not be data in certain fields (e.g. if you added a field to the class and are deserializing an old version of the class). if your code can handle this, than you can probably keep the current uid. if not, then you should probably change it.
in addition to the pre-defined rules, there are advanced usage scenarios where you could even change the type of existing fields and still manage to deserialize the data, but that generally only necessary in extreme situations.
java serialization is very well documented online, you should be able to find all this information in the relevant sun/oracle tutorials/docs.
This only matters if you let Java generate a default UID for your class. It uses the actual members and methods of the class to generate it, thus making it invalid once you change the class structure. If you provide an UID for your class then this only matters if you need to deserialize older versions of your class from a file and such.
Want to define few point to highlight the changes which impacts serialization.
Below you will find the link to Oracle Java Docs for more details.
Incompatible Changes
Incompatible changes to classes are those changes for which the guarantee of interoperability cannot be maintained. The incompatible changes that may occur while evolving a class are:
Deleting fields
Moving classes up or down the hierarchy
Changing a nonstatic field to static or a nontransient field to transient
Changing the declared type of a primitive field
Changing the writeObject or readObject method so that it no longer writes or reads the default field data or changing it so that it attempts to write it or read it when the previous version did not.
Changing a class from Serializable to Externalizable or vice versa.
Changing a class from a non-enum type to an enum type or vice versa.
Removing either Serializable or Externalizable.
Adding the writeReplace or readResolve method to a class, if the behavior would produce an object that is incompatible with any older version of the class.
Link from where the above information is taken
http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678
In Java, does the constructor of a class create an instance of that class? And if it does, does it also initialize the variables of that class?
Constructor doesn’t create the instance of the Class.
Instance creation is done using either:
1.Using Class.forName()
2.ClassLoader loadClass()
3.Using clone()
4.Deserialization
5.Using reflection
6.new keyword
Constructor in java is a special type of method that is used to initialize the object.
Java constructor is invoked at the time of object creation. It constructs the values i.e. provides data for the object that is why it is known as constructor.
Rules for creating java constructor
There are basically two rules defined for the constructor.
1.Constructor name must be same as its class name
2.Constructor must have no explicit return type
Types of java constructors
There are two types of constructors:
1.Default constructor (no-arg constructor)
2.Parameterized constructor
Constructors don't create objects. They merely initialize objects(and their data members) once they are created using parameters(when provided) or to default values.
When you create an instance of the class using new operator, the constructor of the class is called so as to initialize the instance variables.
If the constructor defined is default, then instance variables have to be assigned to the newly created object explicitly.
However when you override a constructor using fields, then the instance variables for that newly created object are assigned during object creation.
I would love to explain this in a very simple language. In the real-world to build something, we need two things first is its prototype/model, and the second is someone who can create it based on that prototype.
A very relevant simple example is to build a house, you first need its blueprint(map), then a constructor who can build it based on that blueprint. So, similarly in the programming language
Object: A real-world entity for which we create a class.
Class: A class describes the "blueprint" of the objects that are made out of it (are instances of it).
For software development, we first have to think about the objects(any real-world entity), then we create a class (blueprint) for it, which contains its attributes.
After creating a class when we need to create one or more objects based on it, for this, we need a constructor to build it.
Whenever we create a new object, we have to use new keyword, and it tells the constructor to create the object.
When you are initialing variables in a class they are just part of the blueprint, based on that, the object will be created. So, without a constructor, you cannot create new objects, but there are some exceptional cases and tricks where you can create them without calling constructors.
I'm trying to understand the usage for getter/setter methods in a class. Let's say we have a class called A with some public instance variables followed by a constructor with parameters where arguments were passed from another class(main) to it. Inside the constructor we let those instance variables equal what was passed.
Now if this class were to be used by another programmer, nothing would stop them from directly accessing/changing the instance variables to something that isn't valid. By making the instance variables private we can eliminate access to those variables. However if we wanted to have those instance variables updated/changed indirectly or under some specific condition or perhaps just letting the person have access to the instance variable, we would create a getter/setter pair for this purpose.
Benefits?:
1.Change instance variable only under certain valid reasons under the set() method
2.So that we can show what the instance variable actually is without giving the programmer who is using this class the ability to change it.
Is this a correct interpretation?
Encapsulation – refers to keeping all the related members (variables and methods) together in an object. Specifying
member variables as private can hide the variables and methods. Objects should hide their inner workings from the
outside view. Good encapsulation improves code modularity by preventing objects interacting with each other in
an unexpected way, which in turn makes future development and refactoring efforts easy.
Being able to encapsulate members of a class is important for security and integrity. We can protect variables from
unacceptable values. The sample code above describes how encapsulation can be used to protect the MyMarks object
from having negative values. Any modification to member variable vmarks can only be carried out through the setter
method setMarks(int mark). This prevents the object MyMarks from having any negative values by throwing an
exception.
Your interpretation is correct. Also (off the top of my head):
It allows the implementation of the class to change (eg if you wish to remove the field and replace it) without forcing consumers to interact with your class any differently.
It allows AOP frameworks to intercept calls to your get / set method.
You can specify permissions via annotations for access to methods.
Yes, your interpretation is correct. But it's because limits of language. For instance in python you don't need write everytime getter or setter, because you can override behavior of member variables. For example:
class MyClass:
def __init__(self, myproperty):
self.myproperty = myproperty
And if everybody use it in way like:
print(new MyClass("test").myproperty)
you can still change behavior of you getter:
class MyClass:
def __init__(self, myproperty):
self._myproperty = myproperty
#property
def myproperty(self):
return self._myproperty + " changed behavior"
or even of setter without touch code what use you class:
#myproperty.setter
def myproperty(self, myproperty):
if len(myporperty) > 0:
self._myproperty = myproperty
See property reference for better example.
if an instance variable is to be used only by methods defined with in its class, then it should be made it as private.If an instance variable must be within certain bounds, then it should be private and made available only through accessor methods[getter as well as Setter] Methods.
I have a class that implements Serializable, it's part of a bigger mesh of objects, it contains a Constructor field, but when it's the Constructors turn to be serialized it throws the NotSerializableException.
I guess I'll have to write the logic myself and recreate the constructor myself every time I deserialize the containing object, but why the heck on earth would the designers of Java wanna create such hassle in the first place? I realize that the ClassLoader is needed to figure out the identity of a class, and that the ClassLoader itself will not be serialized and deserialized, but shouldn't the constructor remember the string arguments used to create it?
Yes, as you realized Constructor is not serializable.
You need to make the Constructor field transient and restore it manually, when needed.
Yes, the Java designers could have made the Constructor class serialized down to the class name and argument list, but that would open a huge can of worms, basically boiling down to the fact that in any given JVM there can be an arbitrary number of classes with that name and there's no sane way to know which one to use when deserializing such an object.
Serialization is a mechanism of storing the state of an object. Based on this definition we can say that the instance variables in an object can be serialized.
Methods are behaviors of the class.
We can set and get the state of an object using the methods. So the methods are related to the instance variables of the class.
Then why can't we serialize the methods in Java ?
What do you plan on 'after' serializing the methods? The state of the object has to be by definition should be only its members. Their behaviors would not come into picture. And serialization is saving the state of the object and not its behaviors.
Methods are always serialized: as bytecode in a class file. There is no practical need to serialize them again.
From OOP perspective, the state of an object is the total state of its non-static fields. Methods are a way to define the object behaviour and are common to all instances (objects) of that class, so they are defined as fields at the Class object not as a field of the object (instance) itself. So serializing the object would store its state thus only its fields, but if you serialize the Class object of your objects you would be serializing the methods of those objects (thought I see no reason why would someone bother himself to do so).
Because method the same for all instances of class, they only driven by its data. If you have class definition in your app - you have it's methods.
But data can change from instance to instance.
A method per say does not have any state, and a serialized method call cannot be used for anything. On the other hand, a serialized thread is conceptually a snapshot or checkpoint of a computation, and that would be useful.
However, threads are not serializable in Java, and it would be really difficult to implement this. (For example, how would you cope with the case where the code of one of the active methods was changed between serializing and deserializing a thread?)