From the effective Java book it states that "An object can always be reused if it is immutable".
String s = "shane";
String p = "shane";
This version uses a single String instance, rather than creating a new one
each time it is executed. Furthermore, it is guaranteed that the object will be
reused by any other code running in the same virtual machine that happens to contain
the same string literal.
What about the below final class which is also immutable?. Can the Point Object be re-used?.
public final class Point {
private final int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y;
}
Can anyone provide me an example of the above immutable class where its object/instance can be re-used?. I am just confused on how the re-usability would occur?.
I am able to relate with String and Integer Classes, but not with user defined classes.
It "can" be reused, in that you could use the same object in multiple places and it would be fine. But it won't be, automatically. The JVM itself manges reuse Integer objects for the range -128 - 127
Integers caching in Java
"intern"ed strings (including literals) similarly are managed by the JVM. The closest to automatic reuse you could have here would be to make the constructor private, and create a factory method:
Point.create(int x, int y)
And have the implementation maintain a cache of objects that you'd like to reuse (like Integers effectively cache -128 to 127) But you'll have to do the work yourself.
Edit:
You'd basically have:
private static final Map<Pair<Integer, Integer>, Point> cache = new HashMap<>();
public Point create(int x, int y) {
Pair<Integer, Integer> key = Pair.of(x, y);
if (cache.containsKey(key)) {
return cache.get(key);
}
Point p = new Point(x, y);
cache.put(key, p);
return p;
}
Edit:
Alternatively, add hashCode() and equals() to the Point class, and just use a HashSet. Would be simpler.
Re usable simply means to change the "reference" variable value.
e.g. an int is can be reused and its value changed
a data type is a little different the reference variable is re-initiated for example using the "new" instane e.g. myframe=new JFrame()
variables declared "final" are a "constant" and are mutable.
The class above itself requires its reference variable at initiation to be declared "final" to be mutable although its contents is effectively mutable, the difficulty is the definition of context of which (variable or class definition) part is the mutable.
Immutability means when an object is created its state at the creation time is going to stay through out its life. And yes, the class you showed and object of that class is immutable, as you are initialing states in constructor and there are no setters.
About the re-use: yes you can reuse the same object over and over where an object of type Point is required, but for that purpose you have to hold on to an object once it's created for that. As #James
suggested, you can use a factory for object creation and that factory can decide if it needs to create a new object or use an existing one when you ask for a Point object.
Related
This is my Class:
public class City
{
private String _cityName;
private Point _cityCenter;
private Point _centralStation;
private long _numOfResidents;
private int _noOfNeighborhoods;
private final long RESIDENTS_CONST_VALUE = 0;
private final int NEIGHBORHOODS_CONST_VALUE = 1;
}
One of my constructor is Copy from other object (same object):
public City(City other)
{
_cityName = other._cityName;
_cityCenter = other._cityCenter;
_centralStation = other._centralStation;
_numOfResidents = other._numOfResidents;
_noOfNeighborhoods = other._noOfNeighborhoods;
}
public Point(Point point)
{
_x = point._x;
_y = point._y;
}
This constructor get another City object and copy it's values.
My question is if what i have done it's OK to avoid aliasing or i need to do something else
The problem is that you are copying the reference from old object to new.It will create problems while copying mutable fields.If both of the objects share common reference to a field, changing the value in one object will affect copied object as well.
The only problem I see is with the reference to the Point class (I'm assuming that we are taking about java.awt.Point). This class is mutable, so the City class you are copying from can change it, and the change will be reflected in your copy also. Use the following code to copy the Point object:
_cityCenter = new Point(other._cityCenter);
_centralStation= new Point(other._centralStation);
The rest of the fields are either primitives or immutable, so it is OK
What you have done looks sane, at least because you haven't copied the Point objects, those are most likely mutable, i.e. if you copy them by simple assignment you would copy only the reference and changes to one object will reflect in the 'copy' -> shallow copy. If you need to make a copy of them too then you'll have to implement a "copy constructor" for them too.
However the standard way of doing this in java is to implment the Colneable interface and override the clone method.
http://www.javapractices.com/topic/TopicAction.do?Id=29
Above is the article which i am looking at. Immutable objects greatly simplify your program, since they:
allow hashCode to use lazy initialization, and to cache its return value
Can anyone explain me what the author is trying to say on the above
line.
Is my class immutable if its marked final and its instance variable
still not final and vice-versa my instance variables being final and class being normal.
As explained by others, because the state of the object won't change the hashcode can be calculated only once.
The easy solution is to precalculate it in the constructor and place the result in a final variable (which guarantees thread safety).
If you want to have a lazy calculation (hashcode only calculated if needed) it is a little more tricky if you want to keep the thread safety characteristics of your immutable objects.
The simplest way is to declare a private volatile int hash; and run the calculation if it is 0. You will get laziness except for objects whose hashcode really is 0 (1 in 4 billion if your hash method is well distributed).
Alternatively you could couple it with a volatile boolean but need to be careful about the order in which you update the two variables.
Finally for extra performance, you can use the methodology used by the String class which uses an extra local variable for the calculation, allowing to get rid of the volatile keyword while guaranteeing correctness. This last method is error prone if you don't fully understand why it is done the way it is done...
If your object is immutable it can't change it's state and therefore it's hashcode can't change. That allows you to calculate the value once you need it and to cache the value since it will always stay the same. It's in fact a very bad idea to implement your own hasCode function based on mutable state since e.g. HashMap assumes that the hash can't change and it will break if it does change.
The benefit of lazy initialization is that hashcode calculation is delayed until it is required. Many object don't need it at all so you save some calculations. Especially expensive hash calculations like on long Strings benefit from that.
class FinalObject {
private final int a, b;
public FinalObject(int value1, int value2) {
a = value1;
b = value2;
}
// not calculated at the beginning - lazy once required
private int hashCode;
#Override
public int hashCode() {
int h = hashCode; // read
if (h == 0) {
h = a + b; // calculation
hashCode = h; // write
}
return h; // return local variable instead of second read
}
}
Edit: as pointed out by #assylias, using unsynchronized / non volatile code is only guaranteed to work if there is only 1 read of hashCode because every consecutive read of that field could return 0 even though the first read could already see a different value. Above version fixes the problem.
Edit2: replaced with more obvious version, slightly less code but roughly equivalent in bytecode
public int hashCode() {
int h = hashCode; // only read
return h != 0 ? h : (hashCode = a + b);
// ^- just a (racy) write to hashCode, no read
}
What that line means is, since the object is immutable, then the hashCode has to only be computed once. Further, it doesn't have to be computed when the object is constructed - it only has to be computed when the function is first called. If the object's hashCode is never used then it is never computed. So the hashCode function can look something like this:
#Override public int hashCode(){
synchronized (this) {
if (!this.computedHashCode) {
this.hashCode = expensiveComputation();
this.computedHashCode = true;
}
}
return this.hashCode;
}
And to add to other answers.
Immutable object cannot be changed. The final keyword works for basic data types such as int. But for custom objects it doesn't mean that - it has to be done internally in your implementation:
The following code would result in a compilation error, because you are trying to change a final reference/pointer to an object.
final MyClass m = new MyClass();
m = new MyClass();
However this code would work.
final MyClass m = new MyClass();
m.changeX();
I know this issue has been addressed many times - but my Java/C++ knowledge is so weak I can barely understand the answers :-( ... what I'd really like is just a super simple example.
In C++ I could write the following:
void func()
{
int x = 3;
add_one(x);
// now x is 4.
}
void add_one(int &var)
{
var++;
}
What I'd like to see now is the simplest way to achieve the same effect with java.
You can't directly. The closest you can get is to put the value in an object, and pass the reference (by value, so the reference gets copied) into the method.
void func()
{
int x = 3;
int[] holder = [x];
add_one(holder);
// now holder[0] is 4. x is still 3.
}
// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
container[0]++;
}
Here I use an array, but the wrapper can be any object.
In java method arguments are pass-by-value, and can't be changed in the function. You must wrap the int - or any other primitive type - in an Object or an array. Passing an Object or an array as a method argument passes a reference which can be used to modify the object.
Java already has Object based wrappers for primitive types, e.g. Integer, but these are immutable by design. Some libraries provide mutable versions of these wrappers; you can also create your own:
public class MutableInt
{
private int val;
public MutableInt(int val)
{
this.val = val;
}
public void setValue(int newVal)
{
this.val = newVal;
}
public int getValue()
{
return this.val;
}
}
void func()
{
int x = 3;
MutableInt wrapper = new MutableInt(x);
add_one(wrapper);
}
void add_one(MutableInt arg)
{
arg.setValue(arg.getValue() + 1);
}
You cannot do this. Java is only pass by value. Primitives are obvious, but the thing that's passed for objects is a reference, not the object itself.
As you can see from the other answers, Java is purely pass by value. Objects are passed by what some call "value-reference". Since an object in java is simply a pointer reference, you can think of the "value" as the address where the object lives on the heap. So when you make a method call, you're copying the "value", aka address, to the method parameter:
Object x = new Object();
foo(x);
During object creation
Heap --> allocate Object (5000)
Variable Declaration
Stack --> allocate local variable (1000)
Variable Assignment
Stack address 1000 set to 5000 (to point to object instance)
So you can see that there are two separate memory allocations here. The "value" of the variable is considered to be it's address on the heap.
Method Call
Stack --> allocate method parameter 8000
Stack address 8000 set to same value as passed parameter 5000
This is why if you reassign an object instance in a method, it does not propagate back to the caller. You would have changed the heap location at stack location 8000. And the calling method's stack location 1000 still has the value 5000 (the original object instance).
Think of it like this in C:
void method(myobject * obj);
You can certainly change fields of "obj", and you can do this locally:
obj = new myobject();
But the caller will still see the original value it passed.
Java has no analog to the & reference operator.
And there are built in classes which can be used for the your purposes. AtomicInteger, AtomicLong, etc... are mutable, though you may suffer a performance hit due to synchronization involved.
I would recommend a generic ValueHolder class to account for all situations where you want to simulate pass by reference:
public class ValueHolder<T> {
private T value;
// getter/setter/constructor
}
Java allows copy by reference for objects and copy by vlaue for primitive types (int,float,etc..). This is so by default and is not subject to change. If you need to change the value of an int inside a function, then you can use the class Integer for example
public int getOneMore(int val) {
return val + 1;
}
I am developing an app that creates a large number of small, immutable Java objects. An example might be:
public class Point {
final int x;
final int y;
final int z;
.....
}
Where it is likely that many instances of Point will need to refer to the same (x,y,z) location.
To what extent does it make sense to try to cache and re-use such objects during the lifetime of the application? Any special tricks to handle this kind of situation?
When it becomes a problem. Otherwise you're just creating a useless layer of abstraction.
Either way, you could easily implement this with a PointFactory that you call to get a Point, which always returns the same object instance for any given x, y and z. But then you have to manage when the points should be removed from cache because they wont be garbage collected.
I say forget about it unless it's an actual issue. Your application shouldn't depend on such a caching mechanism, which would allow you to add it in later if necessary. So maybe just use a factory that returns a new point instance very time for now.
public class PointFactory{
public static Point get(int x, int y, int z){
return new Point(x, y, z);
}
}
The problem you are likely to have is making the object pool light weight enough to be cheaper than just creating the objects. You want to the pool to be large enough that you get a fairly high hit rate.
In my experience, you are likely to have problems micro-benchmarking this. When you are creating a single object type repeatedly in a micro-benchmark, you get much better results than when creating a variety of objects in a real/complex application.
The problem with many object pool aproaches is that they a) require a key object, which costs as much or more than creating a simple object, b) involve some synchromization/locking which again can cost as much as creating an object c) require an extra object when adding to the cache (e.g. a Map.Entry), meaning your hit rate has to be much better for the cache to be worth while.
The most light weight, but dumb caching strategy I know is to use an array with a hashcode.
e.g.
private static final int N_POINTS = 10191; // or some large prime.
private static final Point[] POINTS = new Point[N_POINTS];
public static Point of(int x, int y, int z) {
int h = hash(x,y,z); // a simple hash function of x,y,z
int index = (h & 0x7fffffff) % N_POINTS;
Point p = POINTS[index];
if (p != null && p.x == x && p.y == y && p.z == z)
return p;
return POINTS[index] = new Point(x,y,z);
}
Note: the array is not thread safe, but since the Point is immutable, this doesn't matter. The cache works on a best effort basis, and is naturally limited in size with a very simple eviction strategy.
For testing purposes, you can add hit/miss counters to determine the caches effectiveness for you data set.
It sounds almost like a textbook example of the Flyweight pattern.
How many instances will share the same coordinates, how many will exist at the same time, and how many will be discarded?
Reusing the objects only has benefits if a significant percentage of live objects at one time are duplicates (at least 20%, I'd say) and overall memory usage is problematic. And if objects are discarded frequently, you have to construct the cache in a way that prevents it from becoming a memory leak (probably using soft/weak references).
Remember that caching these objects will influence concurrency and garbage collection in (most likely) a bad way. I wouldn't do it unless the other objects that refer to the points are long lived too.
As for most cases: it depends.
If your object is rather complex (takes a lot of time to instatiate) put can be expressed in a string, it makes sense to create and load them through a static factory method.
This also makes sense if some representations of the object are used more often than others (in your case maybe Point(0,0,0))
e.g
private static final HashMap<String, Point> hash = new HashMap<String, Point>();
public static Point createPoint(int x, int y, int z) {
String key = getKey(x,y,z);
Point created = hash.get(key)
if (created == null) {
created = new Point(x,y,z);
hash.put(key,created);
}
return created;
}
private static String createKey(int x, int y, int z) {
StringBuffer buffer = new StringBuffer();
buffer.append("x:");
buffer.append(x);
buffer.append("y:");
buffer.append(y);
buffer.append("z:");
buffer.append(z);
return buffer.toString()
}
I have a long piece of code that calculates two values (doubles) for me, I use this piece of code in a few places - to stick with DRY principles I should refactor this bit of code to a nice unit testable method. However I cant make it return two doubles, and doubles are primitive so cannot be passed by value and manipulated. The cleanest way I can think of doing this is by making this method return an double[]. Can anyone think of a better way?
Thanks
Firstly, all variables are passed by value in Java, not just primitives. It's just that objects can be mutable. It's important to understand that. For example:
public void addHour(Date date) {
date.setTime(date.getTime() + 3600 * 1000);
}
The date is passed by value but Date is mutable so it can be modified but try and do this:
public void addHour(Date date) {
date = new Date(date.getTime() + 3600 * 1000);
}
and it won't change the date. Why? Because date is a reference but is passed by value.
Secondly, do these doubles relate to each other in some way? If so wrap them in a class than describes this relationship like:
public class Coordinate {
private final double x;
private final double y;
public Coordinate(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() { return x; }
public double getY() { return y; }
}
You could encapsulate them in a class for this purpose.
You could also give a double[] parameter to the method that calculates them and where it will put the calculated values in. This can be rather efficent as the caller code can reuse this array for successive invocations if performance is important.
A class (immutable) with two double fields? Might even want to add some interesting methods to the class.
The other way around is to have the method take a callback object.
double[] arr = {val1, val2};
return arr
or go with a Pair-like class that encapsulates 2 values...
If the two doubles can be thought of as a logical pairing of values, then it might make sense to bundle them in a simple object?
I'm more of a C++ guy, but creating an object of your own called Pair which can hold 2 doubles and can be passed by reference makes sense to me.
Create an new class that has two double properties with getters and setters and constructor if you like (and equals and hashcode...) and make the method return that type of object. A generic way to do that would be a Pair class. This is a common pattern and you should find code snippets everywhere (e.g. in the netbeans code base).
You have several options:
Return an array
Return a List<double>
Return an object of a class that wraps your two doubles
And by the way, Java does not pass objects by reference. It passes pointers to objects by value.
http://javadude.com/articles/passbyvalue.htm
A double array is the most obvious answer. You can make it a bit safer by having a wrapper object like this:
public class MyTwoDoubles {
public MyTwoDoubles(double one, double two) { ... }
public double getOne() { ... }
public double getTwo() { ... }
}
You can rather use Wrapper classes which are of reference types
For every value type you can find a wrapper class.
for your case java.lang.Double can be used,hope this solves the purpose
But still as a good design i suggest you not to alter the object value inside the method.
Instead refactor the code in such a way you call it twice and return two different values then assign it to the original.
As a good practice its not advisible to alter object value inside a method