Calendar variable updates the other when the second is updated?

Asked

Viewed 81 times

1

Hello, I’ve been messing with the Gregoriancalendar class and I’ve come across the following problem:

You had to go from one point in the calendar to the other, then set the first point as the second, then "reset" the second field and go back. basically the following:

GregorianCalendar gc1=new GregorianCalendar();
GregorianCalendar gc2=new GregorianCalendar();
gc1.setTime(meuTempo1);
gc2.setTime(meuTempo2);
while(!gc2.equals(variavel)){//eu tinha que voltar a gc2 até um determinado ponto
//que não necessariamente é igual a gc1.
//percorre o tempo, tirando o tanto de gc2
}
gc1=gc2;//aqui está o problema
gc2.setTime(meuTempo2);

Basically, I walked back through a certain, given a gc1=gc2and I again set gc2 as it was before. The problem is that when I gave the gc2.setTime(meuTempo2); the gc1 variable also received that parameter, i.e., the attributes of gc1 also changed, as if I had placed a second line gc1.setTime(meuTempo2);.

It was easy to fix, just replace gc1=gc2 for gc1.setTime(gc2.getTime()); but I was in doubt, if I instated a new variable, shouldn’t she take the attributes and then be independent of the second one? If not, in which cases can this happen? And if possible, how to treat this problem?

  • I hadn’t read the end of the question. What happens is that you are passing the object reference (memory address), not its value. Another thing, to compare dates and time, if you are using JDK8, it is recommended to use the java.time package classes, these old classes have several problems when comparing.

  • Got it, but as I asked, how to get around this in other classes? using all the setters? in this case still has the setTime, but I have classes that have more than 30 attributes, I use setAtributo(getAtributo()) in all?

1 answer

3


Do gc1=gc2 does not copy the values of the gc2 for gc1. In doing so, you are copying the reference to gc2 for gc1. On a lower level, it means gc1 and gc2 point now to the same memory address where the type object is GregorianCalendar. Therefore, any change in the attribute that is made through the gc1 and of gc2 is affecting the same object.

In the case of GregorianCalendar, you can copy attribute values using the method clone. Something like that:

gc1 = (GregorianCalendar)gc2.clone();

Note that the above code is assigning a new object GregorianCalendar for gc1 with the cloned values of gc2.

  • Does this work for other classes as well? Say, an entity I created for the database myself for example

  • 1

    @Thomasbrazpinto, no. You need to implement your clone method and tell how you want to clone. Usually, what I do is use Reflection to facilitate this cloning. Therefore, I do not attribute by attribute, use Reflection to loop my attributes by copying the values. However, there are a number of questions, such as: and if your object has a Collection, will you clone the Collection tb? So the Clone is made case-by-case.

  • Got it, Thanks for your help!

  • You need to implement the Cloneable interface to use the Clone method, see here: https://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html

  • I kept thinking here, and I had another question, if I left it in the initial way, and made the change in the variable gc1 the amendment would be "seen" in gc2 also?

  • 1

    @Thomasbrazpinto, I think you should change the way you think. Pointer concepts are fundamental for you to understand reference in Java (Java uses pointer, but it abstracts most of the developer). By doing gc1=gc2, you are causing gc1 to point to the same memory address as gc2. This memory address that gc1 and gc2 refer to, contains the object itself, in this case an instance of Gregoriacalendar. Therefore, it is not a matter of "seeing" the change, the question is that both variables point to the same object.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.