Method Creates new instance - java

When a method returns an object, does that method automatically create a new instance of
that object in memory?
For example:
In Java BigInteger class , I use the add method where num1, and num2, lets say, are BigIntegers.
num1.add(num2);
Then I reference it by the same type as in:
BigInteger a = num1.add(num2);
This works and gets the correct data. So the method will create a new instance of that object on the stack?
Just making sure I'm correct about my assumption.
Thanks.

bigInteger.add() does return a new instance, but not all methods do.
What usually returns new object instances that you may run into regularly are:
Constructors
Factorys/Builders
methods operating on immutable objects
BigInteger's add method says that it returns a BigInteger, doesn't say a new BigInteger, but given that the docs also state that BigInteger is immutable, then you can know it's not returning the this object with a modification, so chances are that it's a new object (I suppose it's possible to be some cached object already representing that state, but even if it was, your usage of BigInteger wouldn't change.).

It depends.
With your BigInteger example, it is returning a new instance of the object.
However with something like StringBuilder, you can do
stringBuilder.append("this").append("is").append("a").append("string");
and each .append(String) is returning the same original object, it just allows you to chain the calls together.

Related

New objects: new operator vs serialization

As I understood from what I've read there are basically two ways to create completely new objects in Java: 1) by using new operator and 2) by means of serialization (for deep copying, for example). All other object manipulations (like assigning, for instance) deal with references to existing objects. But what is the difference between the two above mentioned ways in terms of inner logic? It seems that one difference is that serialization somehow doesn't use constructor methods. Am I right? Are there other differences?
By 'inner logic' I mean how the compiler (or whoever deals with it) creates object step-by-step, what algorithm it uses, what methods are used for that and so on. More like what Margaret Bloom was writing about in her answer but in more detail.
FURTHER CONFUSION CLARIFICATION:
So do I get it right that during deserialization the copy of the object:
class Class1 {
static ARRAY_LENGTH = 10;
public class1() {
int[] anArray = new int[ARRAY_LENGTH];
anArray[0] = 5;
...
anArray[9] = -2;
}
}
will include a copy of the array created elsehow (how? since no constructor has been called)? And furthermore, though the original array (before serialization) has been created by using static field (which is lost during serialization) its deserialized copy will nevetheless be identical to the original array?
Serialization and the new operator are completely different things, though they both result in a reference to a newly allocated object.
You can find detailed information about the new operator in chapter 15.9.4 Run-Time Evaluation of Class Instance Creation Expressions of the Java Language Specification.
At run time, evaluation of a class instance creation expression is as follows.
[...]
Next, space is allocated for the new class instance.
[...]
The new object contains new instances of all the fields declared in the specified
class type and all its superclasses.
[...]
Next, the actual arguments to the constructor are evaluated, left-to-right. [...]
Next, the selected constructor of the specified class type is invoked. This results in
invoking at least one constructor for each superclass of the class type.
The value of a class instance creation expression is a reference to the newly created
object of the specified class. Every time the expression is evaluated, a fresh object
is created.
Editing mine
So long story short, new allocates space for a new object (specifically space for its fields), initialize its fields with their default values and invokes the chosen constructor.
Java Serialization is another matter entirely.
The ability to store and retrieve JavaTM objects is essential to building all but the most transient applications. The key to storing and retrieving objects in a serialized form is representing the state of objects sufficient to reconstruct the object(s).
Emphasis mine
Which means that serialization was designed to allow the programmer to save objects states into a persistent medium (abstracted into stream within Java) and read them back.
As such, deserializiation does not invoke constructors since the object state is restored automatically by reading it out the stream. You can override the default behavior though.
Reading an object from the ObjectInputStream is analogous to creating a new object. Just as a new object's constructors are invoked in the order from the superclass to the subclass, an object being read from a stream is deserialized from superclass to subclass. The readObject or readObjectNoData method is called instead of the constructor for each Serializable subclass during deserialization.
Emphasis mine
Said that, I would like to stress out how using new and serialization are totally unrelated things from a conceptual point of view.
In the first case you are creating your own new object, in the latter you are reading a previously saved object (possibly by someone else).
Even though they can be thought as similar for their final result, you should have, in your mind, a really clear distinction between the twos.
New operator is use to create object in memory whereas serialization is the concept belongs to data persistence and it could also be used for creating a new object in memory.
If an object implements java.io.Serializable it will be marked as Serializable Object and data in object could be converted to byte stream (serialize) and we could use this byte stream data to create a new object in memory (desrialize). Java supports 2 objects for serialize and deserialize, they are ObjectInputStream and ObjectOutputStream
Disagree with deserializiation does not invoke constructors:
In fact, Deserializiation just does not invoke the constructors defined in the class body. As depends on java.reflect, it of course need to invoke constructors to produce a Object from a Class. It just invoke the custom constructors created by sun.reflect.ReflectionFactory.newConstructorForSerialization(Class<?> var1, Constructor var2).

Best design approach for creating Immutable Class

I am reading about the specific guidelines that needs to be followed while creating Immutable Class in Effective Java.
I read that In Immutable class method should not allowed to be overridden otherwise overridden method may change the behaviour of method. Following are the design approaches available in java to solve this problem :-
We can mark class final but as per my understanding, it has a one disadvantage that it makes the class inextensible.
Secondly is to make individual methods final but I can not get other disadvantage besides that we need to individually mark each method as final in order to prevent overridding.
As per book,better approach is to make the constructor private or package-private and provide public static factory method for creating object.
My question is: Even if we include private or default constructor in the class, it cannot be extended anymore in same package (in other package in case of package-private constructor), it has a same problem which the first one had. How is it considered as the better approach than the previous ones?
An immutable object should not be extensible. Why?
Because extending it will allow either direct access to fields (if they are protected which would allow writing methods that change them), or adding state which may be mutable.
Imagine we wrote a class FlexiblyRoundableDouble that extends Double, which has an additional field roundingMode that lets us choose a "rounding mode". You could write a setter for this field, and now your object is mutable.
You can argue that if all the methods are set as final, you cannot change the original behavior of the object. The only methods that could access your roundingMode field are new methods that are not polymorphically available if you assign your object to a Double variable. But when a class's contract says that it's immutable, you make decisions based on that. For example, if you write a clone() method or copy constructor for a class that has Double fields, you know that you don't need to deep-copy the Double fields, as they do not change their state, and can therefore be safely shared between the two clones.
Also, you can write methods that return the internal object without fearing that the caller will then change that object. If the object was mutable, you'd have to make a "defensive copy" of it. But if it's immutable, it's safe to return a reference to the actual internal object.
However, what happens if someone assigned a FlexiblyRoundableDouble to one of your Double fields? That object would be mutable. The clone() would assume it isn't, it will be shared between two objects, perhaps even returned by a method. The caller would then be able to cast it back as a FlexiblyRoundableDouble, change the field... and it will affect other objects that use that same instance.
Therefore, immutable objects should be final.
All this has nothing to do with the constructor issue. Objects can be safely immutable with public constructors (as demonstrated by String, Double, Integer and other standard Java immutables). The static factory method is simply a way utilizing the fact that the object is immutable, and several other objects can hold references to it safely, to create fewer objects with the same value.
Providing a static factory method gives you room to implement the Flyweight Pattern.
They're stating that you should hide the possibility of creating a new object using a constructor, and should rather make a call to a method which checks if an object with similar state exists in the "object pool" (a map filled with objects waiting to be re-used). Not re-using immutable objects is a waste of memory; this is why String literals are encouraged, and new String() is shunned (unless needed).
class ImmutableType {
private static final Map<Definition, ImmutableType> POOL = new HashMap<>();
private final Definition definition;
private ImmutableType(Definition def) {
definition = def;
}
public static ImmutableType get(Definition def) {
if(POOL.contains(def))
return POOL.get(def);
else {
ImmutableType obj = new ImmutableType(def);
POOL.put(def, obj);
return obj;
}
}
}
Definition stores the state of the ImmutableType. If a type with the same definition already exists in the pool, then re-use it. Otherwise, create it, add it to the pool then return it as the value.
As for the statement about marking the class final, immutable types should not be extensible in the first place (to avoid possibly modifying behavior). Marking every method final is just crazy for immutable classes.

How nested method call works

Can anybody explain this how this line of code works:
Rational sum = a.add(b).add(c);
I don't understand how object b (which is an argument) is receiving a method?
This is called method chaining. The method add() actually returns a reference of the currently modified object or a new object of the same type on which the method was invoked. Say suppose the object referred to by a is a BigInteger , when you invoke a.add(b) , it returns a BigInteger object whose value is a+b , and hence you can invoke .add(c) on that object again.
Rational sum = a.add(b).add(c);
// is equivalent to
Rational temp = a.add(b);
Rational sum = temp.add(c);
Method chaining is not required. It only potentially improves readability and reduces the amount of source code. It is the core concept behind building a fluent interface.
A sample illustration:
This practice is used mostly in Builder pattern, you can find this pattern in API itself in StringBuilder class.
I don't understand how object b (which is an argument) is receiving a method?
No your understanding is wrong , a.add(b) means you are invoking method add() on object a and passing it a reference of object b . The resultant object which the method a.add(b) returns is of the same type as a , and then in succession you call the method .add(c) on the returned object passing a reference of object c to that method.
Its fluent chaining
Each method in the chain has to return a class or an interface. The next method in the chain has to be a part of the returned class.
in your case a.add(b) returning some calss/interface and then calling add(c) on that and that method returns your sum

new object is created or not?

I am reading Effective Java by Joshua Bloch. It confuses me in the item 1, where it states
A second advantage of static factory method is that, unlike constructors, they are not required to create a new object each time time they're invoked.
Isn't the static factory method meant to create a new object each time it is invoked?
//constructor
Orange(){
}
//static factory method
static Orange staticFactoryMethod(){
return new Orange;
}
Won't calling either the constructor or the staticFactoryMethod create an instance of Orange?
Orange orange=new Orange();
Orange orange=Orange.staticFactoryMethod();
A static factory does not always need to create a new object.
You can have this:
static Orange staticFactoryMethod(){
return new Orange();
}
But you can also have something like
static Orange staticFactoryMethod(){
Orange o = ... //find an orange in a basket of available oranges that has been already initialized
return o;
}
Take a look at Integer.valueOf(int i). If i is within the range -128 to 127 this method will not create a new Integer object but return a value from cache.
Isn't the static factory method is mean to create a new object each time it is invoked?
No. The purpose of a factory method is to return a suitable object. That object might be an object that was created earlier. It all depends on the intended semantics of the factory, and of the objects. For instance, it the objects are immutable and their object identity has no special significance, then sharing instances can be a worthwhile optimization.
For example, the Integer.valueOf(int) method returns an Integer method that may (for small integers) have been created and used previously. This has the advantage of reducing the number of Integer instances that are created ... and need to be garbage collected when they are finished with.
You could also argued that String.intern(String) is a form of factory method, though it has the unusual property that (in recent implementations) it never allocates new strings.
A third example is a thread or connection pool which tries to recycle objects that have been returned to the pool.
By contrast, if the "client" of your API has to use new to create instances, there is no opportunity for your API to do this kind of thing. That is Bloch's point.

Why the object of wrapper classes like Boolean etc. direct takes value without initialization but property of object is not allow?

Why the object of wrapper classes like Boolean etc. direct takes value without initialization but property of object is not allowed?
Code:
class TestByte{
public static void main(String[] a) {
Byte b=125; System.out.println(b);
}
}
do you mean why can you use methods without throwing a NullPointerException from a wrapper class object just by using Byte b = 25 instead of explicitly initializing the Byte object as Byte b = new Byte(25)??
Well, if you DID meant that, its because ever since java 1.5 assigning values to Wrapper references can be done without explicitly instantiating the object. This is called Auto-Boxing, Which implicitly creates the wrapper objects instance and assigns it with the value.
Such that: Byte b = 25 its the same as Byte b = new Byte(25). There are a few differences with the boxing version that influence the result comparing Wrapper values by reference if you assign a value in the range of a byte.. but well that is a whole different thing xD..
Well Abhishek, the purpose of contructors to initialize objects is to do any preparation work to get that object live. Since wrapper classes and String hold only data, the only preparation to inialize them is to provide them necessary values. So, we actually don't need to call new for them.

Categories