I'm coming from the C++ world and I can't find what is the Java alternative (if any) to the following:
struct SomeStruct
{
SomeStruct(){}
SomeStruct(const SomeStruct& rhs)
{
*this = rhs;
}
};
The reason why I need this is that I have a cache of existing objects, so I don't want to create another instance but just to 'clone' the existing one, something like this:
public class SomeObject
{
private static Hashtable _objects;
SomeObject()
{
SomeObject obj = _objects.get(some_key);
if (obj != null) {
// *this = obj;
// instead of:
// this.something = obj.something;
// this.something1 = obj.something1;
// this.something2 = obj.something2;
// a zillion fields....
}
}
};
EDIT:
Sorry, I confused some things (still need to learn both Java and C++).
Thank You
The closest is Object.clone() but read the relevant section from Effective Java first.
There are probably simpler ways to do what you want if you remove some of your requirements. For example, if you make your objects immutable then you don't need to copy the data into another object. Instead you can return a reference to the original object. This is much faster than a memberwise copy, and has lots of other benefits too, such as making it easier to write thread-safe code.
There's no direct equivalent. Object.clone() is the closest, but it creates a new instance and performs a shallow copy. You could write something generic using reflection though.
public class SomeObject
{
private static Hashtable _objects;
public static SomeObject getInstance(SomeKey some_key)
{
return _objects.get(some_key);
}
}
It is unclear from your question whether you are trying to achieve a pure cache of immutable objects, or keep a cache of 'template' objects, and return copies that can then be mutated by the client. I am going to assume the latter.
Assuming that you do want to return copies of originals. there is no really nice way to implement a copy constructor in Java. Clone is marginally nicer, so you should hide the constructor behind a static factory method:
public static SomeObject getInstance(...) {
SomeObject cached = ...;
if (cached != null) {
return cached.clone();
}
...
}
Perhaps in your particular case you can separate the immutable and stateful parts of the objects? If so, some changes to your object model can lead to cleaner (and more efficient) code?
In Java, if you want to have a constructor corresponding to a copy constructor, you have to implement it yourself. In some cases, this means you have to copy fields from one object instance into another, while in other cases it means you have to implement a full deep copy - recursively iterate through the reference fields of the parameter in the copy ctor.
This depends on what you want - should the objects hashtable be copied as well? Or should both objects share the reference to it? For more info, see this question.
I don't know of any generic way to copy all the contents of fields from one object to another existing without using;
reflections
generated code.
copy using the Unsafe class.
Reflections is easier to use at runtime, but not as efficient as generated code. (But pretty close) I generate my data model so I use this option.
The Unsafe class is faster than reflection, but not cross platform and unsafe. It is almost as fast as generated code. ;)
In terms of speed, if generated code is 1x, Unsafe is 1.5 - 2x and reflection is 2 - 4x slower for highly cached data. For poorly cached data you won't see a difference.
You should use the Singleton pattern. You create a static instance of SomeObject and work with that instance.
private static class SingletonHolder {
public static final SomeObject INSTANCE = new SomeObject();
}
public static SomeObject getInstance() {
return SingletonHolder.INSTANCE;
}
But don't fall in the Singleton trap, limit calls to getInstance()!
Related
I am pretty new to Java, I have to convert C/C++ code to Java and I am running into obstacles. Because of the way variables are passed to the methods, their modification in the method is not straightforward, and I have no idea what is the most reasonable approach to take. Sorry for the pseudocode examples, I hope they will clearly explain what I am talking about without delving into unnecessary details.
I need something that would be equivalent to C
ModifyMyString(type1 &t1,type2 &t2);
(return type doesn't matter, it can be void) as I need the function to modify both t1 and t2.
I can easily modify one of the variables, say t1, by declaring in Java
type1 modifyMyString(type1 t1, type2 t2);
and assigning the returned value to
t1 = modifyMyString(t1,t2);
but it is only half of a success, as the new value of t2 is lost.
I can declare new class
class JustToPassTwoVariables {
type1 t1;
type2 t2;
JustToPassTwoVariables(type1 tt1, type2 tt2) { t1 = tt1; t2 = tt2; }
}
and do something like
JustToPassTwoVariables jtptv = modifyMyString(JustToPassTwoVariables(t1,t2));
but I feel like it is clumsy and makes the code unreadable.
In desperation I could also resign the idea of using a modifyMyString method, and repeat all the code locally in each place I would call modifyMyString - but it makes even less sense than using JustToPassTwoVariables class.
Is there a correct (or at least widely used, accepted as a standard, whatever) strategy to code such things in Java?
The recommended way in java is (in some people's opinion the clumsy way) to create a class containing the two fields and return an instance of that class.
I feel that it is much less clumsy if you stop and think about what the method is actually doing, and taking care to properly name both the method and the class returning the two values.
The simple answer is no. This sort of feature is not allowed in Java.
The correct way to do it is to pass in the object to be modified not the two variables. After all in virtually all cases those variables are already wrapped in an object, in cases where they aren't they often easily can be.
Either split the function into two functions and call it once for each variable, or wrap the variables into an object and pass that object into the function.
Don't forget Java allows Inner Classes which makes this sort of thing less painful.
You can't return two values from a method in java. The way is to return an object and set all the values in it. i.e. In your case, you need to create a value container class i.e. say Result class that will have two fields storing the type1 and type2 value in it. The return type of the method would be of value container object type i.e. say Result instance with two fields in it - type1 and type2
Example :
Result result = modifyMyString(t1,t2);
result.getT1(); //gets t1 value
result.getT2(); // gets t2 value
Please learn about setters and getters in Java to work on the class or object level fields
In Java if you want to do this you would generally make type1 and type2 into object whose values can be modified. The method can then modify the values of the parameters to get the desired effect. For example :
void myMethod(type1 arg0, type2 arg1) {
arg0.setValue(newValue0);
arg1.setValue(newValue1);
}
If type1 and/or type2 do not have any way of changing their values (e.g. they are of type String) then you would either make a wrapper class for each of them e.g.
class Type1Wrapper {
private type1 type1;
type1 getType1() {
return type1;
}
void setType1(type1 newType1) {
type1 = newType1;
}
}
or you would make a wrapper for both of the types simultaneously like you have in your question (although the method return type will be void and the method will modify your wrapper's values)
There are several methods to modify a group of objects "of the same type/class". The simplest of them being, add them to a "list" pass that list to your modification function, do whatever modifications/additions/deletions etc.. The list reference will be automatically available outside with the "changes made in the called function" .
So, you can do
List<String> l = new ArrayList<String>();
l.add("Hello");
l.add("world");
ModifyMyString(l);
// here also l = "hello" , "world" , "added"
public void ModifyMyString(List l)
{
l.add("added"); // now l = "hello" , "world" , "added"
}
Java is an OO language so to get the best out of it you should look to an OO solution. It's hard to give you a definite solution with this abstract example but this is how I would approach this.
You mention that t1 and t2 both need to be updated by this modify procedure/method. Also that they need to be updated at the same time, if they were unrelated then you could just call modify on each string in turn. If these two strings are related like this then it's likely they belong to the same type.
So we need a class containing type 1 and type 2.
public class TypeContainer
{
private String type1;
private String type2;
.. getters and setters
}
Obviously you'll want a better class name.
You suggest something similar yourself but call it JustToPassTwoVariables. This is missing the point of OO. You could write a simple wrapper like this and pass it to some other method to modify the values but a more OO approach would be to add the modify method to this class itself.
...
public void modfiy(String val1, String val2)
{
type1 = val1;
type2 = val2;
}
...
I'm not sure what your modify is trying to do but in this case I would probably have these as two separate setter methods. This is quite an abstract example!
Basically I would avoid having the modify method in some other unrelated class. You should look to group common related attributes into classes and then write methods in those classes for any actions you need to take (such as modify).
Trying to convert a procedural C program into an OO Java program sounds like a PITA. It's a complete paradigm shift. Having said that I have seen automated conversions which while technically Java are still very procedural. Not very pretty and hard to maintain but was done for political reasons.
Java discourages this strategy beacause in-variable should be immutable, but if you have to migrate from C/C++/C# and you have a lot of "void function with parameters passed as in/out", you can create a Custom "Reference" class like this and you can incapsulate the original object.
public class CustomRef {
public Object internal;
public CustomRef(Object object) {
this.internal=object;
}
}
then when you call
CustomRef ref1= new CustomRef(myParams1);
CustomRef ref2= new CustomRef(myParams2);
myFunction(ref1, ref2);
myParams1 = ref1.internal;
myParams2 = ref2.internal;
the function is
void myFunction(CustomRef ref1, CustomRef ref2) {
Object param1 = ref1.internal
// a lot of code
ref1.internal = param1;
}
really discouraged way ... such as using ArrayList, arrays [] to "pass by reference".
NOTE: this way is a waste of resource; CustomRef instance should be reused through object pool (another discouraged way).
I would use a StringBuffer. You can initialize it with a String and convert it back to a String
I'm trying to understand this operator function written in C++ and convert it to Java.
Class& Class::operator=(const Class& In) {
properties = In.properties;
return *this;
}
Does this simply copy instance and properties of a class object? For which I've already written something:
public static Class copy(Class obj) {
//returns new instance of Class individual
Class copy = new Class(obj.row_num, obj.col_num, obj.input_length, obj.output_length, obj.max_arity, obj.function_length, obj.levels_back);
copy.genes = obj.genes.clone();
return copy;
}
Am I on the correct track? Many thanks for your help.
Ampersand & designates a reference in C++. It is needed to provide the behavior similar to what Java objects provide "out of the box", because Java manages objects through references.
There is no copying going on in C++ when a reference is passed. In fact, avoiding copying is a major reason for using const references as function parameters.
The code that you show does not perform copying either: it changes its state based on the value being "assigned". The closest way of modeling this in Java would be providing an assign(Class other) method that changes the current state to match that of the object passed in:
Class assign(Class other) {
this.properties = other.properties;
return this;
}
You will need to use this method in place of C++'s assignment, like this:
Class clOne(args1);
Class clTwo(args2);
clOne = clTwo; // Using the assignment operator
becomes this:
Class clOne = new Class(args1);
Class clTwo = new Class(args2);
clOne.assign(clTwo); // Using the assignment method instead of the operator
You're pretty much on the right track. The copy assignment operator in C++ is used when directly assigning (copying) from one object to another. As Java objects are only accessible via references, such assignments are meaningless. To match the C++ semantics exactly, the Java equivalent would be:
public Class copy(Class obj) {
row_num = obj.row_num;
col_num = obj.col_num;
// etc., etc.
genes = obj.genes.clone();
return this;
}
Am I on the correct track?
Kind of. But not quite. C++ distinguishes between reassigning an existing object and creating a new one.
Java doesn’t. You cannot reassign to an existing object in Java1 (but you can of course reassign a reference). In Java, in order to copy an object (rather than assign a reference to it), you would usually use a copying constructor:
Class(Class other) {
// Copy members of `other` into `this`.
}
And then use it as follows:
Class x = new Class(something here);
Class y = new Class(x); // copy
In particular, this is what all the Java containers implement. I would not rely on clone. First of all, clone should only be used if the class implements the tag interface Cloneable. Second of all, clone’s design is arguably broken and its use is not recommended.
1 Well you could of course reassign the members of an object (unless they are final), and you could mimic C++’s copy assignment operator by providing a method assign to do that. However, this isn’t the conventional way of doing things in Java (although it might have its place in some exceptional instances).
I ran across this problem, which has been driving me nuts. In a nutshell, I instantiate two objects of the same class. When I run a method in one object, the other object is affected too as if I called a method on a 2nd object explicitly. I was wondering if someone could please give me a hand on this.
Suppose, I have class Portfolio...
public class Portfolio implements Cloneable {
public ArrayList<Instrument> portfolio;
private String name;
private String description;
public Portfolio() {
portfolio = new ArrayList<Instrument>();
}
public Portfolio(Portfolio copyFrom) {
//attempt to copy the object by value
this.portfolio = (ArrayList<Instrument>) copyFrom.portfolio.clone();
this.name = copyFrom.name;
this.description = copyFrom.description;
}
public void applyStress(Stress stress) {
this.portfolio.set(0,this.portfolio.get(0)+1;
}
1st constructor is used to instantiate an object, etc. 2nd constructor is used to copy an object by value.
A method applyStress is used to run through sum calculations. in our case I simplified the method, so that it does nothing but adds +1 to whatever is in the object.
So I would instantiate an object as
Portfolio p = new Portfolio();
then I would assign to a portfolio field, some instruments;
p.portfolio = someInstrumentList;
then I would copy by value the portfolio p into pCopy:
Portfolio pCopy = new Portfolio(p);
So at this time I am have two objects that are the same. Further one is a copy-by-value object. Changing values of fields in pCopy does not affect same fields in p.
Now, when I run a method applyStress on p, then the values of the instrument list in pCopy will also change.
In other words, if p.portfolio.get(0) == 1, then after p.applyStress, I would expect to see that p.portfolio.get(0) is 2 and pCopy.portfolio.get(0) is 1
But what I see instead is p.portfolio.get(0) is 2 and pCopy.portfolio.get(0) is also 2
I do not understand why this happens. It is not the static modifier issue, as there is no static modifiers. Anyone has any ideas?
The clone method applied to you your ArrayList reference does a shallow copy, not a deep copy. This implies that whatever you had in the original collection is shared by the cloned one.
This means that you need to clone every instrument as well, or provide a copy constructor for every one of them.
this.portfolio = new ArrayList<Instrument>();
for(Instrument toBeCopiedInstrument : copyFrom.portfolio){
this.portfolio.add(new Instrument(toBeCopiedInstrument ));
}
By default .clone() does what is called a shallow copy, this means it just copies a reference to the objects that are held in the List that is being cloned, it doesn't actually copy the objects themselves to new instances.
What you need to do is implement a custom deep copy for the List and each of the items held in the list. But deep clone is a broken concept and implementation in Java.
A copy constructor isn't a really good pattern in Java either, because you end up copying references as well in most cases and every object you inject to the constructor has to follow the same copy constructor semantics all the way down the chain. Unlike C++, this is manual, tedious, unmaintainable and error prone process!
.clone() and implements Cloneable are some of the most complex to get correct concepts in Java. They are rarely needed in well designed applications. That is, if you are using .clone() you are probably doing it wrong. If making bit wise copies of your objects are part of your design for something other than storage, you might want to revisit your design.
Josh Bloch on Design
Object's clone method is very tricky. It's based on field copies, and
it's "extra-linguistic." It creates an object without calling a
constructor. There are no guarantees that it preserves the invariants
established by the constructors. There have been lots of bugs over the
years, both in and outside Sun, stemming from the fact that if you
just call super.clone repeatedly up the chain until you have cloned an
object, you have a shallow copy of the object. The clone generally
shares state with the object being cloned. If that state is mutable,
you don't have two independent objects. If you modify one, the other
changes as well. And all of a sudden, you get random behavior.
Immutable
A better pattern is to make everything immutable. That way you don't need separate instances, you can share instances until they need to change, then they change and you have a new instance with the new data, that can be shared without any side effects.
How do I make defensive copies of a Mutable Object which contains a mutable field in an Immutable Object?
class ImmutableObject {
private final MutableObject immutable_field;
ImmutableObject(MutableObject y) {
this.immutable_field = y;
}
}
class MutableObject {
public int mutable_field;
}
The MutableObject does not have a constructor that lets me set the field.
The MutableObject's current state should be captured in the Immutable Object and never changed.
What you need to do is in
MutableObject return_immutable_field() {
return immutable_field;
}
Change to:
MutableObject return_immutable_field() {
MutableObject tmp = new MutableObject();
tmp.mutable_field = immutable_field.mutable_field;
return tmp;
}
For an explanation see http://www.javapractices.com/topic/TopicAction.do?Id=15
Well, assuming that there is nothing to be done about the declaration of the mutable object class, one could leverage reflection (Class.newIntance() and Class.getFields()) to create a new object and copy field values. You could also implement deep copying in this manner. If the class supports serialization, then another hackish approach would be to serialize the object and then save a deserialized copy. If it is possible to fix the design of the mutable object, though, that would be a better approach.
Edit
For the particular example that you've given, Romain's answer does what you want. If you have a general mutable object that doesn't provide a mechanism for copying it and for which the type may not be known until later, then the reflection approach is how one would implement a copy mechanism.
I have code that looks like this:
public class Polynomial {
List<Term> term = new LinkedList<Term>();
and it seems that whenever I do something like term.add(anotherTerm), with anotherTerm being... another Term object, it seems anotherTerm is referencing the same thing as what I've just inserted into term so that whenever I try to change anotherTerm, term.get(2) (let's say) get's changed too.
How can I prevent this from happening?
Since code was requested:
//since I was lazy and didn't want to go through the extra step of Polynomial.term.add
public void insert(Term inserting) {
term.add(inserting);
}
Code calling the insert method:
poly.insert(anotherTerm);
Code creating the anotherTerm Term:
Term anotherTerm = new Term(3, 7.6); //sets coefficient and power to 3 and 7.6
New code calling the insert method:
poly.insert((Term)anotherTerm.clone());
Which unfortunately still doesn't work due to clone() has protected access in java.lang.Object, even after doing public class Term implements Cloneable{
The solution is simple: make Term immutable.
Effective Java 2nd Edition, Item 15: Minimize mutability:
Immutable objects are simple.
Immutable objects can be shared freely.
Immutable objects make great building blocks for other objects.
Classes should be immutable unless there's a very good reason to make them mutable.
If a class cannot be made immutable, limit its mutability as much as possible.
Make every field final unless there is a compelling reason to make it non-final
Something as simple and small as Term really should be made immutable. It's a much better overall design, and you wouldn't have to worry about things like you were asking in your question.
See also
What is meant by immutable?
This advice becomes even more compelling since the other answers are suggesting that you use clone().
Effective Java 2nd Edition, Item 11: Override clone judiciously
Because of the many shortcomings, some expert programmers simply choose to never override the clone method and never invoke it except, perhaps, to copy arrays.
From an interview with author Josh Bloch:
If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken.
DO NOT make Term implements Cloneable. Make it immutable instead.
See also
How to properly override clone method?
Why people are so afraid of using clone() (on collection and JDK classes) ?
OK, replacing my old answer with this, now that I understand the question and behavior better.
You can do this if you like:
public void insertTerm(Term term) {
polynomial.insert(new Term(term));
}
and then create a new Term constructor like this:
public Term(Term term) {
this.coefficient = term.coefficient;
this.exponent = term.exponent;
}
That should work.
EDIT: Ok, I think I see what it is you're doing now. If you have this class:
public class Polynomial
{
List<Term> term = new LinkedList<Term>();
public void insert(Term inserting)
{
term.add(inserting);
}
}
And then you do this:
Polynomal poly = new Polynomal()
Term term = new Term();
poly.insert(term);
term.coefficient = 4;
...then the object term is the same object as poly.get(0). "term" and "poly.get(0)" are both references to the same object - changing one will change the other.
Question is no so clear, but i just try , when you are adding the objects , add anotherTerm.clone()
It sounds like you are not instantiating new Objects, just referencing the same one. You should instantiate a new Term, either with Term term = new Term(); or by cloning term.clone().
EDIT to be able to be cloned, Term need to implement the Cloneable interface. That means that you are responsible for how the new copy of a Term should be defined.
Hard to tell without seeing the code that calls the insert method, but sounds like that is the problem.