Create instance from superclass instance - java

Consider the following case:
class A {
int x;
int y;
}
class B extends A {
int z;
}
Now, somewhere in the code this classes are used like this:
A objA = getAFromSomewhere();
B objB = null;
And in a certain situation I want to do something like
objB = objA; // can't do this
objB.z = someZ;
Of course the real objects are a bit more complicated, so it's not just about copying two ints. But they aren't overly complex either.
I know I can write a constructor for B like this:
public B(A anA) {
this.a = anA.a;
this.b = anA.b;
this.z = 0;
}
But if that's really the only way, I prefer merging the additional members of B into A.
update considering the answers
My question was not clear enough. I understand that objB = objA; can't work (thus I asked for "something like", meaning something with comparable code complexity) and I know about the issues with shallow vs deep copies.
What I was looking for is a possibility to copy the members of a base class (let's say using clone()). You may understand that copying every member manually is a bad solution as it adds complexity and redundancy to the code. Thanks for your replies anyway!

There's no trivial solution to this because there's no one-size-fits-all solution. Basically you don't have all the information within a B, so you can't guarantee you would have a "sensible" B object.
You probably just want to create a constructor in B which takes an A and copies all the A data into the new B.

If you're not scared of commons-beanutils you can use PropertyUtils
import org.apache.commons.beanutils.PropertyUtils;
class B extends A {
B(final A a) {
try {
PropertyUtils.copyProperties(this, a);
}
catch (Exception e) {
}
}
}

There is a (relatively) trivial solution!
Implement a constructor in class B that takes an instance of class A and copies the fields.
One of the reasons there's no generic solution in the language itself is because of the problem of deep copying.
For example, if the source object contains further Objects, as opposed to plain types, what would the generic copy operator do? Just copy the reference (giving a shallow copy), or make real copies?
What then if one of those objects is a Collection? Should it also copy every element of the collection, too?
The only logical conclusion would be to perform a shallow copy, but then you haven't really got a copy at all.

Perhaps you could do this:
class A {
int x;
int y;
A(A a) {
this.x = a.x;
this.y = a.y;
}
}
class B extends A {
int z;
B(A a) {
super(a);
z = 0;
}
}
You're still listing every field, but only once per class.

I am shocked too. :)
You really cannot do this: objB = objA;.
Because Renault and BMW are cars but not all cars are BMW.
Thank about A as Car, B as BMW.
Now you say:
Car car = new Renault();
BMV bmv = car; // you cannot do this. This is exactly your case.

...not because this is what people should do but more because I felt like a challenge, here is some test code which does a simple copy of the objects (using setter and getter methods):
import java.lang.reflect.Method;
import org.junit.Test;
public class ObjectUtils {
#Test
public void test() {
A a = new A();
B b = new B();
a.setX(1);
a.setY(2);
this.copyProperties(a, b);
}
private void copyProperties(Object obja, Object objb) {
Method m[] = obja.getClass().getDeclaredMethods();
for(int i=0;i<m.length;i++) {
try {
String name = m[i].getName();
if(name.startsWith("get") || name.startsWith("is")) {
Class rtype = m[i].getReturnType();
String setter = name.replaceFirst("^(get|is)","set");
Class s = objb.getClass();
Method method = s.getMethod(setter,rtype);
Object[] args = new Object[1];
args[0] = m[i].invoke(obja);
method.invoke(objb,args[0]);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
class A {
int x;
int y;
/**
* #return the x
*/
public int getX() {
return x;
}
/**
* #param x the x to set
*/
public void setX(int x) {
this.x = x;
}
/**
* #return the y
*/
public int getY() {
return y;
}
/**
* #param y the y to set
*/
public void setY(int y) {
this.y = y;
}
}
class B extends A {
int z;
/**
* #return the z
*/
public int getZ() {
return z;
}
/**
* #param z the z to set
*/
public void setZ(int z) {
this.z = z;
}
}
}

If you do not need full functionality of A, there is also an option to create class B, holding internal copy of A instance and implementing some minimal subset of methods via C interface by proxying them to instance.
class A implements IC {
int x;
int y;
public C() {
...
}
}
class B implements IC {
private A _a;
public B(A a) {
_a = a;
}
public C() {
_a.C();
}
}

Assuming that your class A has a very neat and clean setter and getter method naming convention like
setXXX(Object xxx) and corrresponding getXXX() which returns the same thing (Object xxx ) as a param passed to setXXX()
I have written a utility method using reflection
public static B createSubclassInstance(A a) throws SecurityException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Method[] aMethods = Class.forName("package.A").getDeclaredMethods();
B b = new B();
for (Method aMethod : aMethods) {
String aMethodName = aMethod.getName();
Class param = aMethod.getReturnType();
if (methodName.startsWith("get")){
String setterMethodName = methodName.replaceFirst("get", "set");
Method bMethod = Class.forName("package.B").getMethod(setterMethodName);
Object retValA = aMethod.invoke(a,null);
bMethod.invoke(b,retValA);
}
}
return b;
}

If you change your method to create B objects, you can just do what you want using:
objB = (B) objA;
objB.z = someZ;
This can even be inlined, but you need parentheses:
((B) objA).z = someZ;
If not, you have to go the long way using constructors:
objB = new B(objA);
objB.z = someZ;
In this case I would recommend to copy the fields of the superclass in the superclass. Else, if you add a field to that class later, you may forget to change the copying more easily.
class A {
int x;
int y;
public A(A objA) {
x = objA.x;
y = objA.y;
}
}
class B extends A {
int z;
public B(A objA) {
super(objA);
}
}
I prefer merging the additional members of B into A.
You can do this if your classes A and B share the same package or if the variables in your A class are declared as protected. Then you can just access the fields of the superclass.
class A {
protected int x;
protected int y;
}
class B extends A {
int z;
void merge(A a){
super.x = a.x;
y = a.y; // you do not *need* to use the super keyword, but it is a good hint to
// yourself if you read your program later and might wonder ‘where is
// that y declared?’
}
}
Useage, of course, is:
objB = new B();
objB.merge(objA);
objB.z = someZ;

I think best way is to use a factory method to create B objects from A objects.
class BFactory
{
public static B createB(A a)
{
B b = new B();
copy(a,b);
return b;
}
private static <X,Y> void copy(X src,Y dest) throws Exception
{
List<Field> aFields = getAllFields(src.getClass());
List<Field> bFields = getAllFields(dest.getClass());
for (Field aField : aFields) {
aField.setAccessible(true);
for (Field bField : bFields) {
bField.setAccessible(true);
if (aField.getName().equals(bField.getName()))
{
bField.set(dest, aField.get(src));
}
}
}
}
private static List<Field> getAllFields(Class type)
{
ArrayList<Field> allFields = new ArrayList<Field>();
while (type != Object.class)
{
Collections.addAll(allFields, type.getDeclaredFields());
type = type.getSuperclass();
}
return allFields;
}
}

Related

final variable initialization in subClass

public class A {
final int x;
public A(int x) {
if ( this instanceof B ) {
if(x > 5)
this.x = x;
else
this.x = 0;
} else {
this.x = 0;
}
}
}
public class B extends A {
public B(int x) {
super(x);
}
}
I want to put the if in the class B to avoid instanceof ( because i have more sub classes and the x value depends on the subClass ), but when i do that i get compiler error: Constructor call must be the first statement in a constructor!
Can you help me avoid instanceof?
There are two ways we can initialize constants, first one is to initialize them in place on the same line as in the answer by Adam, second is to use constructors, which you're trying to implement.
Using inline initialization is generally more flexible because we are not bound to the rules of the constructor, like this(...) or super(...) call should be the first in the constructor. However if you do want to use constructor for the purpose you can use method containing logic as inline call as argument to the this(...) or super(...). This method should be static as the instance of the class doesn't exist yet as we're in constructor. Following is a simple solution for the same.
class A {
final int x;
public A(int x) {
this.x = 0;
}
}
class B extends A {
public B(int x) {
super(getValueForX(x));
}
private static int getValueForX(int x) {
return x > 5 ? x : 0;
}
}
Just create an abstract method in A and implement it in your derived classes like this:
public abstract class A {
final int x;
abstract int calculateX(int x);
public A(int x) {
this.x = calculateX(x);
}
}
public class B extends A {
#Override
int calculateX(int x) {
return x + 1;
}
public B(int x) {
super(x);
}
}

How to create multiple instances to an implementation of an interface?

Let A be an interface which has a method a.
Let B be a class which implements A and has method a and has three fields 1,2,3.
I want to use two instances of A (meaning B), both of which have different values of 1,2,3 (present in cfg file) at two different places.
Can someone provide a simple and elegant solution to this problem using Guice.
You don't tell how the class that uses your dependency references the interface. I assume that you want to reference it with an interface.
What you can use, is annotation that will denote which instance you want to use. Assume that these are your implementations:
interface A {
void a();
}
class B implements A {
private int value;
void a() { ... }
B(int value) { this.value = value; }
}
And these are the classes that use the implementations:
class UserFirst {
private A a;
#Inject
UserFirst(#Named("first") A a) { this.a = a; }
}
class UserSecond {
private A a;
#Inject
UserSecond(#Named("second") A a) { this.a = a; }
}
The thing that decides which implementation is going to be injected is the #Named annotation. You can also define your annotations, but usually it's an overkill.
Now, in order to bind that, you can do something like this:
class MyModule extends AbstractModule {
#Override
protected void configure() {
A first = new B(1);
B second = new B(2);
bind(A.class)
.annotatedWith(Names.named("first")).toInstance(first);
bind(A.class)
.annotatedWith(Names.named("second")).toInstance(second);
}
}
Here's the full documentation: https://github.com/google/guice/wiki/BindingAnnotations
if I do understand you correctly, you might want to make B abstract so that you can override the methods which you want to change, if this is the case.
Now I can only assume that by fields you mean field-varriables. I would then recommend you to make them NON-static and change them in the constructor when you make an object. Then read the values of 1,2,3 in the public static void main method and send them upon creating a new object:
public class B implements A {
private int x,y,z;
/**
* This would now be the constructror
*/
public B(int x, int y, int z){
this.x = x;
this.y = y;
this.z = z;
}
/**
* Then some return functions
*/
public get1() { return this.x; }
public get2() { return this.y; }
public get3() { return this.z; }
/**
* Then whatever methods you get from A
*/
public int someMethodFromA(int x, int y){
return x*y;
}
}
public static void main(String[] args) {
/**
* Some random method to read inn from CFG file
*/
int x1 = readXFromCFG();
int y1 = readYFromCFG();
int z1 = readZFromCFG();
B objectB1 = new B(x1,y1,z1);
int x2 = readXFromCFG();
int y2 = readYFromCFG();
int z2 = readZFromCFG();
B objectB2 = new B(x2,y2,z2);
int x3 = readXFromCFG();
int y3 = readYFromCFG();
int z3 = readZFromCFG();
B objectB3 = new B(x3,y3,z3);
}

Java consecutive method calls

So I've seen, in many places, calling methods of a class like:
SomeClass obj = new SomeClass();
obj.addX(3).addY(4).setSomething("something").execute();
I don't think I completely understand how that works. Is each method independent of each other, so the above is equal to:
obj.addX(3);
obj.addY(4);
obj.addSomething("something");
obj.execute();
Or are they designing their class structure in some other fashion that allows for this. If they are how are they designing their classes to support this?
Also, does that have a specific name? Or is this just calling methods on a class?
That would be method chaining. It can do one of two things.
Each call to a method returns this which allows you to continue to call methods on the original instance.
public class SomeClass
{
private int _x = 0;
private int _y = 0;
private String _something = "";
public SomeClass addX(int n)
{
_x += n;
return this;
}
public SomeClass addY(int n)
{
_y += n;
return this;
}
public SomeClass setSomething(String something)
{
_something = something;
return this;
}
// And so on, and so on, and so on...
}
Each method call returns a new instance of the class with everything copied/updated appropriately. This makes the class immutable (so you don't accidentally modify something that you didn't mean to).
public class SomeClass
{
private int _x = 0;
private int _y = 0;
private String _something = "";
public SomeClass(int x, int y, String something)
{
_x = x;
_y = y;
_something = something;
}
public SomeClass addX(int n)
{
return new SomeClass(_x + n, _y, _something);
}
public SomeClass addY(int n)
{
return new SomeClass(_x, _y + n, _something);
}
public SomeClass setSomething(String something)
{
return new SomeClass(_x, _y, something);
}
// And so on, and so on, and so on...
}
Some people have also mentioned Fluent Interfaces. Fluent Interfaces utilize method chaining to create an API that provides something along the lines of a Domain Specific Language which can make code read much more clearly. In this case, your example doesn't quite qualify.
they modify object's state and return the same object back mostly
class Number{
int num;
public Number add(int number){
num+=number;
return this;
}
}
you can call it like
new Number().add(1).add(2);
most of the time the use case is to return new Object to support immutability
Each of those methods return an instance. For example, the call to
obj.addX(3)
will return the same instance obj, so the call
obj.addX(3).addY(4)
will be equivalent to
obj.addY(4)
This is called method chaining.
The methods are implemented like this:
public SomeClass addX(int i) {
// ...
return this; // returns the same instance
}
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test1 abc = new Test1();
abc.add1(10, 20).sub1(40, 30).mul1(23, 12).div1(12, 4);
}
public Test1 add1(int a, int b)
{
int c = a + b;
System.out.println("Freaking Addition output : "+c);
return this;
}
public Test1 sub1(int a, int b)
{
int c = a - b;
System.out.println("Freaking subtraction output : "+c);
return this;
}
public Test1 mul1(int a, int b)
{
int c = a * b;
System.out.println("Freaking multiplication output : "+c);
return this;
}
public Test1 div1(int a, int b)
{
int c = a / b;
System.out.println("Freaking divison output : "+c);
return this;
}
}

How to make a function inside a class mutuable?

Imagine I have a class
class A {
int a;
int b;
A(int a, int b) {
this.a=a; this.b=b;
}
int theFunction() {
return 0;
}
void setTheFunction([...]) {
[...]
}
}
And for every new object I instantiate, I want to be able to define theFunction() in a new way by calling setTheFunction( [...] ). For example, I want to do something like this:
A test = new A(3,2);
test.setTheFunction ( int x = a*b; return x*x+2; );
System.out.println(test.theFunction()); // Should return (3*2)*(3*2)+2 = 38
Or something like this:
A test2 = new A(1,5);
test.setTheFunction ( for(int i=0; i<b; i++) a=a*b*i; return a; );
Now, what I could of course do is write all of those functions inside class A and use a switch statement to determine which one is to pick. But if I don't want the algorithm of theFunction() hardcoded inside my class A, is there any way to do something similar to the above? And what would setTheFunction() look like? What type of argument would you have to pass?
You can use Callable.
public class A<V> {
public int a;
public int b;
private Callable<V> callable;
public A(int a, int b) {
this.a = a;
this.b = b;
}
public V theFunction() {
try {
return callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setTheFunction(Callable<V> callable) {
this.callable = callable;
}
}
Then, to use it:
final A<Integer> test = new A<Integer>(3, 2);
test.setTheFunction(new Callable<Integer>() {
int x = test.a * test.b;
return x * x + 2;
});
System.out.println(test.theFunction());
Of course, the generic typing of A isn't necessary, but I've added it to make this answer to be less restricted.
If you always need to operate on the same arguments, you could solve this by defining an interface such as:
public interface MethodPerformer {
int performOperation(int a, int b);
}
Then pass in implementations of this to your setTheFunction method. Finally, invoke the operation when you call the other method:
class A {
int a;
int b;
MethodPerformer performer;
A(int a, int b) {
this.a=a; this.b=b;
}
int theFunction() {
performer.performOperation(a, b);
}
void setTheFunction(MethodPerformer performer) {
this.performer = performer;
}
}
Clearly additional code would be required to check the performer is not null. Perhaps take a performer in the constructor?
Instead of using a setter, the more natural way is to use an anonymous sub-class. This way the compiler will check it behaves correctly and has access to the right variables.
public class Main {
static abstract class A {
protected int a, b;
A(int a, int b) {
this.a = a;
this.b = b;
}
public abstract int theFunction();
}
public static void main(String... ignored) {
A test = new A(3, 2) {
#Override
public int theFunction() {
int x = a * b;
return x * x + 2;
}
};
System.out.println(test.theFunction()); // Should return (3*2)*(3*2)+2 = 38
A test2 = new A(1, 5) {
#Override
public int theFunction() {
for (int i = 1; i < b; i++) a = a * b * i;
return a;
}
};
System.out.println(test2.theFunction());
}
}
prints
38
15000
With this you can solve any kind of problem, that involves any kind of public variable of A (but can work with package private variables as well, if the AFunction implementation resides in the same package), that a function may use to perform it's operation. It's just not as compact as it can be in other languages than java.
interface AFunction
{
int call(A a);
}
class A
{
int a;
int b;
//giving it a default implementation
private AFunction f = new AFunction()
{
#Override
public int call(A a)
{
return a.a * a.b;
}
};
A(int a, int b)
{
this.a = a;
this.b = b;
}
int theFunction()
{
return f.call(this);
}
void setTheFunction(AFunction f)
{
this.f = f;
}
}
By the way as AlexTheo points out, all answers so far (except for Peter Lawrey's) are a form of the strategy design pattern.
The easiest way to do this is defining "A" as an interface instead of a class. You declare theFunction() without actually implementing it.
In client code, everytime you need "A", you instantiate a so-called anonymous inner class.
For example:
new A() { #Override public int theFunction() { ...your implementation... } };

Is this an immutable class?

I have no idea what immutable class should look like but am pretty sure this one is. Am I right? If I'm not please specify what should be added/removed.
import java.io.Serializable;
public class Triangle implements IShape, Serializable {
private static final long serialVersionUID = 0x100;
private Point[] points;
public Triangle(Point a, Point b, Point c) {
this.points = new Point[]{a, b, c};
}
#Override
public Point[] getPoints() {
return this.points;
}
#Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (getClass() != obj.getClass()) return false;
Point[] trianglePoints = ((Triangle) obj).getPoints();
for (int i = 0; i < points.length; i++){
if (!points[i].equals(trianglePoints[i])) return false;
}
return true;
}
}
Will this do the trick?
#Override
public Point[] getPoints() {
Point[] copyPoint = {
new Point(points[0]),
new Point(points[1]),
new Point(points[2]),};
return copyPoint;
}
Point class:
import java.io.Serializable;
public class Point implements Serializable {
private static final long serialVersionUID = 0x100;
public int x;
public int y;
public int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public Point(Point that) {
this.x = that.x;
this.y = that.y;
this.z = that.z;
}
public boolean equals(Object obj) {
// assume this is a typical, safe .equals implementation
// that compares the coordinates in this instance to the
// other instance
return true;
}
}
No, you can change what's in the Points array. If you want to make it immutable, have the getter hand out a copy of the Points array, not the original.
try this:
Triangle triangle = new Triangle(a, b, c);
triangle.getPoints()[1] = null;
System.out.println(Arrays.toString(triangle.getPoints()));
Also Point needs to be immutable (as Nikita Rybak points out). For how to copy arrays see how to copy an array in Java.
No, it's not. You expose the Point[] and a caller could modify its contents. Also, your class is not final, so someone could subvert it by subclassing it.
No, it's definitely mutable.
Not only do you expose the actual Point[] array, you don't defensive-copy (Bloch 2nd ed., Item 39) the Point objects themselves when taking them in via the constructor.
The Point[] array could have items
removed or added to it, so it's
mutable.
You could pass in Points a,
b, and c, then call setX() or setY()
on them to change their data after
construction.
Close. For one thing, an immutable class should make it's fields final, but that's not a requirement.
However, you are exposing an array through the getter, and that is not immutable. Make a defensive copy using Arrays.copyOf(array, length):
#Override
public Point[] getPoints() {
return Arrays.copyOf(this.points,this.points.length);
}
Here's what I'd do to make this class immutable, with the help of Guava. I see from the #Override in the code you posted that IShape seems to require a Point[] from the getPoints() method, but I'm ignoring that for the sake of example since the use of object arrays is a rather poor idea, especially if you want immutability (since they cannot be immutable and all).
public final class Triangle implements IShape, Serializable {
private final ImmutableList<Point> points;
public Triangle(Point a, Point b, Point c) {
this.points = ImmutableList.of(a, b, c);
}
public ImmutableList<Point> getPoints() {
return this.points;
}
// ...
}
Point should also be more like:
public final class Point implements Serializable {
/*
* Could use public final here really, but I prefer
* consistent use of methods.
*/
private final int x;
private final int y;
private final int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
// getters, etc.
}
In order to be an immutable class, it is not enough that your methods promise not to change the object. In addition to having all fields be private and the methods not allow changing, you must also guarantee that the subclasses have the same promise of immutability. This includes making the class itself final, and ensuring that no references to the fields are ever returned.
A short, but excellent treatment of this can be found in this article:
http://www.javaranch.com/journal/2003/04/immutable.htm
Not only do you need to provide an immutable copy of the internalised array, you also need to make sure that the Point object is immutable.
Consider the following use of the Point class in the standard Java API:
Point a = new Point(1,1);
Point b = new Point(1,1);
Point c = new Point(1,1);
Triangle triangle = new Triangle(a, b, c);
System.out.println(Arrays.toString(triangle.getPoints()));
c.setLocation(99,99);
System.out.println(Arrays.toString(triangle.getPoints()));
It is not immutable because ...
Triangle t1 = new Triangle(new Point(0,0), new Point(0, 10), new Point(10, 10));
Triangle t2 = t1;
System.out.println( t1.getPoints()[0] ); // -> 0
t2.getPoints()[0].x = 10;
System.out.println( t1.getPoints()[0] ); // -> 10
Thus the class is not immutable because you can change the state of an instance (internal Point[] exposed) and this also changes the state of a reference to the same instance.
To make it a true immutable class, you would need methods to separately get X and Y from each point, for example:
public int getPointX(int point) { return points[point].x; }
public int getPointY(int point) { return points[point].y; }
or
public Point getPoint(int point) { return new Point(points[point]); }
or return a copy of the points like you suggested in your edit.
In addition to what others have already noted, you should:
Make your Triangle class final to prevent the creation of mutable Triangles by subclasses.
Declare all the fields final, to catch accidental modification of fields by the class itself.
In "Effective Java," Joshua Bloch provides a list of rules for immutable classes in general, in Item 15: Minimize Mutability.
1) Make members private and final - so
private Point[] points; //should be
private final Point[] points;
2) Make class final so it cannot be sub-classed
3) Exclusive access to mutable members (array) - meaning return copy of and not the reference to mutable members
For the best treatment of this subject refer to Joshua Bloch, Effective Java- item 15
This could be a better Point implementation.
import java.io.Serializable;
public final class Point implements Serializable {
private static final long serialVersionUID = 0x100;
private final int x;
private final int y;
private final int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public Point(Point that) {
this(that.x, that.y, that.z );
}
public boolean equals(Object obj) {
// assume this is a typical, safe .equals implementation
// that compares the coordinates in this instance to the
// other instance
return true;
}
}
Other than exposing the array (as getters are wont to do) and not being final, being serialisable is "problematic".
As a very nasty man, when deserialising, I can get another reference to the internal array. The obvious fix for this is:
private void readObject(
ObjectInputStream in
) throws ClassNotFoundException, IOException {
ObjectInputStream.GetField fields = in.readFields();
this.points = ((Point[])(fields.get("point", null)).clone();
}
That still leaves the problem of points not being final and exposing the object without points initialised (or worse, but a bit thoeretical, partially initialised). What you really want is a "serial proxy", which you can find out about on the internets...
Note: If you implement equals you should also implement hashCode, probably toString and possible Comparable.
Point itself doesn't have to be immutable for Triangle to be immutable. You just have to do a lot of defensive copies so that nobody has a reference to the Point objects stored in the Triangle.
Also, shouldn't triangle a-b-c equal triange b-c-a (and 4 other permutations)
A immutable class example with mutable field:
public final class ImmutabilityTest {
private final int i;
private final C c1;
ImmutabilityTest(int i, C c1){
this.i = i;
this.c1 = c1;
}
public int getI() {
return i;
}
public C getC1() {
return (C)c1.clone();//If return c1 simply without calling clone then contract of immutable object will break down
}
#Override
public String toString() {
return "ImmutabilityTest [i=" + i + ", c1=" + c1 + "]";
}
public static void main(String[] args) {
ImmutabilityTest i1 = new ImmutabilityTest(10, new C(new D("before")));
System.out.println(i1);
i1.getC1().getD1().name = "changed";
System.out.println(i1);
}
}
class C implements Cloneable{
D d1;
public C(D d1) {
super();
this.d1 = d1;
}
public D getD1() {
return d1;
}
public void setD1(D d1) {
this.d1 = d1;
}
#Override
public String toString() {
return "C [d1=" + d1 + "]";
}
public C clone(){
C c = null;
try {
c = (C) super.clone();
c.setD1(c.getD1().clone());// here deep cloning is handled if it is commented it will become shallow cloning
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
class D implements Cloneable{
String name;
public D(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "D [name=" + name + "]";
}
public D clone(){
D d = null;
try {
d = (D) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return d;
}
}

Categories

Resources