tags:

views:

616

answers:

11

Say way have a variable (let's say String Str) and the value of Str starts of as " " then as some code is running it is set to "test" then somewhere else in the code it is changed again to say "tester". Now in the program I want to find out what the previous value of Str was. Is this possible in Java?

So I am saying that the variable gets changed twice, and you want to find out what Str was before it got changed for the second time. So in the example above the latest value of Str would be "tester" but I wanted to find out what Str was before this (assuming you had no idea what it was before it was changed to tester) in this case I would want to be able to find out that Str was "test".

Is it at all possible to do this in Java?

+14  A: 

No, it's not possible, you have to save the previous value before you change it to do what you're asking for.

Stefan Thyberg
+1  A: 

Indeed, this is not possible. You'd have to create your own String class that had some sort of memory to achieve this.

Kris
No custom class will accomplish this, since it is the variable assignment that is being changed. The object itself is not being manipulated.
Robin
I think he's suggesting a wrapper class that has both get() and getPrevious() and a setter that manages saving previous values.
Outlaw Programmer
+7  A: 

Not as a native part of the language, no. You could write a setter that saved the current (previous?) value when the String changes, though.

private String str;
private String prev;

setStr(String s)
{
    prev = str;
    str = s;
}

Then just write a separate getter for prev.

Of course, this solution relies on you always using the setter to change the value of str.

Also, as deworde points out, if your program doesn't need this information, then you shouldn't modify your program to save it. If you need the information for debugging purposes you can just set a watch in your IDE's debugger.

Bill the Lizard
Of course, this would potentially greatly increase the memory footprint of your application.
Bryan Oakley
If you used it a lot, yes it could effectively double your memory footprint.
Bill the Lizard
You could write a class to do this (at the cost of even more memory).
Tom Hawtin - tackline
Yeah, if you find yourself doing it a lot, you could dedicate a class to it.
Bill the Lizard
Well, yes, but if you're using it for debugging/testing, you could then change the setter back for release.A debugger might still be your best option.
deworde
@deworde: Agreed. This is wasteful if you only need the previous value during debugging. I assumed it was to be used in the program.
Bill the Lizard
+1  A: 

In addition to what Stefan said, I would recommend a List structure of some kind containing all the historical values.

When you want to change the value, just add a new value to the end of the list. When you want to get the current value, just look at the last value. If you want to see previous values, start from the end of the list.

A: 

If you could find the previous state of the program, there would never be any garbage to collect and the program would very quickly run out of memory.

For specific variables, you could use, say, a LIFO stack. Instead of an assignment you would push to the stack. Instead of reading the variable, you would peek. The contents of the stack can be examined to find historical values.

Another approach would be to use instrumentation. This allows you to, with sufficient skill and patience, rewrite byte code to do what ever you want.

Perhaps you want to stand back a bit and look at what you are actually trying to achieve.

Tom Hawtin - tackline
A: 

I don't know the reasons for wanting to do this, but I'm guessing it's debugging of some kind.

If you're using eclipse, you can set breakpoints that trigger when a variable changes. That might achieve what I assume you're trying to get to.

izb
+2  A: 

If you really have a strong need for this you could use the following code:

public class Main 
{
    public static void main(final String[] argv) 
    {
        SavedValue<Integer> i;

        i = new SavedValue<Integer>();
        i.set(7);
        System.out.println(i.get());
        System.out.println(i.getOld());
    }
}

class SavedValue<T>
{
    private T oldValue;
    private T value;

    void set(final T val)
    {
        oldValue = value;
        value    = val;
    }

    T get()
    {
        return (value);
    }

    T getOld()
    {
        return (oldValue);
    }
}

Perhaps you could explain why you want the old value? I am sure we can give you much better answers if we knew why yoiu wanted it.

TofuBeer
+2  A: 

It looks like you're using this for debugging, am I right?

Visual Studio, or any decent debugger should allow you to print a trace of the value every time it's set just by putting a "tracepoint" before and after all the calls that set the value.

You just alter the properties of a normal breakpoint to print a statement rather than halt execution. In VS2005 this is done by:

  • Bringing up the breakpoint window
  • Right-clicking on the breakpoint
  • Selecting the option "When Hit...".
  • Selecting "Print a Message" and entering a message
  • Making sure that "Continue Execution" is still selected.

This normally slows the program down significantly while debugging, so it's of little use for time-dependent debugging; but it's still allowed me to follow a variable's states (ABCDFEGH...)

Of course, if you do want to halt execution, just dump a normal breakpoint in.

deworde
You can add a watch to IntelliJ so that it shows you the new value every time it changes. I'm sure other IDEs like Eclipse can do this as well.
duffymo
+1 - you can set a watch on a variable in Eclipse and NetBeans deguggers as well.
Bill the Lizard
+4  A: 

Simple answer, no.

However, you could use:

AOP

An AOP framwork, such as AspectJ could intercept assignments to a variable.

See AspectJ pointcut reference

JavaBeans Property Change Support

You could use standard JavaBean setters, getters to encapsulate your field. Then you can register listeners on a bean to listen out for property changes, and even veto that change.

See JavaBean Spec for more information.

Example listener:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

public class MyBeanListener implements PropertyChangeListener,
        VetoableChangeListener {

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        System.out.printf("Notifed of property changed event: %s => %s%n", evt
                .getOldValue(), evt.getNewValue());

    }

    @Override
    public void vetoableChange(PropertyChangeEvent evt)
            throws PropertyVetoException {
        System.out.printf("Notified of vetoable change event: %s => %s%n", evt
                .getOldValue(), evt.getNewValue());
    }
}
toolkit
+1  A: 

You already got the two simple answers:

  • No, Java itself doesn't allow that
  • You can use setters and implement a mechanism to keep the old value(s)

But there is a third one which I haven't seen so far:

It should be possible to write an Aspect in AspectJ that triggers on the assignment. So it would have a similar effect as a setter, without the actual setter. If you are working with code that you don't want to or cannot change this might be an option.

Note that while AspectJ isn't Java the result is normal byte code, so it should be compatible with most environments.

Of course instead of using AspectJ you could do this with CGLIB.

Jens Schauder
A: 

This is in fact possible using something called a Historical Debugger, and it is accomplished by instrumenting the bytecode so that any assignment to the variable is recorded.

Gooogle Bil Lewis Historical Debugger for one example. Note that most of this software is in what you'd call an 'initial beta' phase.

Omer Raviv