does anyone know how to replace variable value after a program that changes it? I tried static variable before, but it doesn't save after you close the program.
For example
import java.lang.Math;
public class Main {
static int A1;
public static void main (String [] args) {
A1=(int) (1+Math.random()*10);
}
}
Let's say the first time the program is run, A1 holds a value of 5. Is it possible that next time the program is run, A1 still holds a value of 5 instead of zero? (before reaching the main method)
Thanks
Of course not, when the program exits the portion of memory it was using is freed for other programs. The only way to do it is writing to a file and restore the value from the file at the initialization of the program.
The most easy to do that in Java is to use Preferences API, the most easy way to use it is
prefs = Preferences.userRoot().node(this.getClass().getName());
String ID = "A1";
if (prefs.getInt(ID, -1)
prefs.putInt(ID, (int) (1+Math.random()*10));
A1 = prefs.getInt(ID, -1)
to get more info, juste Google "java preferences api"
Related
I want to create an application that shows a user how many times he opened or used the software. For this I have created the code below. But it is not showing correct output: when I run the application first it is showing 1 and then the second time I run it it is also showing 1.
public Founder() {
initComponents();
int c=0;
c++;
jLabel1.setText(""+c);
return;
}
I’m unsure whether I’m helping you or giving you a load of new problems and unanswered questions. The following will store the count of times the class Founder has been constructed in a file called useCount.txt in the program’s working directory (probably the root binary directory, where your .class files are stored). Next time you run the program, it will read the count from the file, add 1 and write the new value back to the file.
static final Path counterFile = FileSystems.getDefault().getPath("useCount.txt");
public Founder() throws IOException {
initComponents();
// read use count from file
int useCount;
if (Files.exists(counterFile)) {
List<String> line = Files.readAllLines(counterFile);
if (line.size() == 1) { // one line in file as expected
useCount = Integer.parseInt(line.get(0));
} else { // not the right file, ignore lines from it
useCount = 0;
}
} else { // program has never run before
useCount = 0;
}
useCount++;
jLabel1.setText(String.valueOf(useCount));
// write new use count back to file
Files.write(counterFile, Arrays.asList(String.valueOf(useCount)));
}
It’s not the most elegant nor robust solution, but it may get you started. If you run the program on another computer, it will not find the file and will start counting over from 0.
When you are running your code the first time, the data related to it will be stored in your system's RAM. Then when you close your application, all the data related to it will be deleted from the RAM (for simplicity let's just assume it will be deleted, although in reality it is a little different).
Now when you are opening your application second time, new data will be stored in the RAM. This new data contains the starting state of your code. So the value of c is set to 0 (c=0).
If you want to remember the data, you have to store it in the permanent storage (your system hard drive for example). But I think you are a beginner. These concepts are pretty advanced. You should do some basic programming practice before trying such things.
Here you need to store it on permanent basic.
Refer properties class to store data permanently: https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html
You can also use data files ex. *.txt, *.csv
Serialization also provide a way for persistent storage.
You can create a class that implements Serializable with a field for each piece of data you want to store. Then you can write the entire class out to a file, and you can read it back in later.Learn about serialization here:https://www.tutorialspoint.com/java/java_serialization.htm
I'm using JPL to do some SWI-Prolog queries in a Java program. When I want to create a new Query, I would like to be able to use jpl.Util.textToTerm to directly instanciate Terms from a user input, without parsing it myself.
The problem is that this method seems to always parse variable identifiers (i.e. something that starts with a capital letter) as anonymous variables (i.e. something that starts with _).
For example, jpl.Util.textToTerm("X") returns a jpl.Variable that has name _1 instead of X, which is obviously a problem since that means I won't be able to access any bindings after querying.
Creating a jpl.Query directly from a string, like new Query("reverse([1,2],X)") has the exact same problem.
_1 it's not an anonymous variable, so the problem is less important than it appears at first glance.
Variables with the same name (actually, the same variable) will have the same representation once returned from the JPL interface. Otherwise, you should file a bug of the mailing list...
You should use read_term family of predicates passing as option variable_names(Vars). For instance, on the REPL
?- read_term_from_atom('a(X,Y,X)',T,[variable_names(L)]).
T = a(_G1434, _G1435, _G1434),
L = ['X'=_G1434, 'Y'=_G1435].
edit a quick test reusing JPL test infrastructure (I've named the file TestQuery.java)
import java.util.Map;
import org.jpl7.Query;
import org.jpl7.Term;
public class TestQuery {
public static void main(String argv[]) {
Query q = new Query("X = 1");
Map<String, Term>[] solutions = q.allSolutions();
System.out.println(solutions[0]);
}
}
outputs
./run.sh
Compiling TestQuery
JPL demo: TestQuery
{X=1}
so, maybe I don't understand your problem in first place, sorry... Are you using an up-to-date installation ?
This question already has answers here:
Value does not update in while loop unless printed out [duplicate]
(4 answers)
Closed 8 years ago.
I have the following piece of code
public String ls() throws IOException, InterruptedException {
String pwd = getPWD();
String inodePath = "Upload/Files" + pwd + "inode";
// Request the inode file first
Peer.setFileReceivedCheck(false);
Inode i = new Inode();
i.requestInode(pwd + "inode");
boolean fileCheck = Peer.getFileReceivedCheck();
System.out.println(fileCheck);
while (fileCheck == false) {
System.out.println(); // DOES NOT WORK IF THIS LINE IS REMOVED!!
fileCheck = Peer.getFileReceivedCheck();
}
System.out.println(fileCheck);
return i.readFromInode(inodePath);
}
In the above java method, the fileCheck variable keeps track of when a file is downloaded from the network and becomes true when the file download completes; so that the functions returns when the file download is completed.
The weird problem which I am facing is that if I remove the above line (the one with just a println); the method is stuck in the while loop and does not return even though the file has been downloaded! Any idea as to why this is happening?
EDIT: This is not running in a separate thread. The file download code in another class (Peer.java) is running in a separate. Again, the getter for fileCheck is out of the thread.
Please, in the name of $DEITY, do not use hot polling. Stop. Right now. You are wasting billions of cycles, you will make the whole system less responsive, while you wait for something to come over the network. Use a callback - we are in 2014, it's not rocket science.
That said, repace the contents of the while loop with this:
Object o = new Object();
synchronized(o) {
fileCheck = Peer.getFileReceivedCheck();
}
What happens is that your check probably just returns a non-volatile field, and the compiler is free to optimize that away - unless your code hits a synchronization point.
Did you try adding a small timeout (100ms), instead of println()?
My program has the following structure:
void main (String[] args) {
Object largeObject = longInitialization();
interestingLogic(largeObject);
}
The longInitialization code never changes during development. BUt whenever I change the interestingLogic, I have to run the program again and wait for the longInitialization to complete.
Unfortunately I cannot serialize largeObject because it is not Serializable and I don't have the code to it.
Is there a trick by which I can save the initialization time? Maybe, in some way save the state of the JVM just after initialization, and then always start from that state?
You can make little modification of code:
main(){
Object largeObject = longInitialization();
boolean debug = true;
while(debug){
interestingLogic(largeObject);
}
}
now run program in debug mode. Set breakpoint at interestingLogic call and use code hotswap debug mode in IDE. read more about hotswap in Eclipe: Java Hotswap with Eclipses and Remote Debugging on Local Machine
//Edit:
One more option. Just write mock of largeObject.
You will need a new object to call interestingLogic(largeObject). You can make changes to the new object while the driver program is waiting for user input.
void main (String[] args) {
Object largeObject = longInitialization();
boolean anotherTry = true;
String answer = "";
Scanner input = new Scanner(System.in);
while (anotherTry) {
Object newobject = NewObject();
newobject.interestingLogic(largeObject).
System.out.print("Run Again Y/N");
answer = input.nextLine();
if (answer.equalsIgnoreCase("N")) {
anotherTry = false;
}
}
}
If the large object is not needed immediately, you could decorate it with a "lazy initializing" wrapper, and invoke the "longInitialization" just before you want to access it.
A second solution could be "cloning" it by marshalling/unmarshalling it to an xml file
Because you said "...cannot serialize largeObject..." there is no way to persist an object across JVM lifetimes (since you don't have the source). But, you have code that initializes/uses the largeOject. Create a serializable debugLargeObject that acts like the real largeObject and use debugLargeObject during development.
Not without a lot of work. You need a minor refactor, as shown by Guido, then you need to reload the NewObject class each time through the loop (or whatever). In other words, your VM needs to be able to remove the NewObject class, then reload it, each time you change the code.
There are commercial products which do this (see JRebel, for example). You can roll your own (see this StackOverflow topic: Unloading classes in java?). You can hotswap, if you're very careful about your interestingLogic. But ultimately, you need to swap out that class somehow.
My j2me application call destroyApp() and notifyDestroyed() when it wants to be closed
when I run it on blackberry, in the second launch the static variables will have the same values they had in previous run.
Why they don't get the initial value? How can I make sure the application initialize static variables?
This discussion at Blackberry support forums suggests that it is a known issue with BlackBerry MIDlets - at least with those using static push registries. Workarounds they suggest are either re-define static variables in startApp or get rid of static push.
This post looks worth extensive quoting, since there is a nice code example and issue analysis:
The simplest example I could come up with is this:
public class BasicMIDlet extends MIDlet {
private static byte myByte = Byte.MIN_VALUE;
public void startApp() {
System.out.println("My byte: " + myByte);
myByte = Byte.MAX_VALUE;
notifyDestroyed();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
You would expect myByte to output to -128 every time the app starts,
but this is my output:
--------------------------------------------------------
Starting BBTest
Started BBTest(159)
Foreground BBTest(157)
My byte: -128 <------------
Foreground net_rim_bb_ribbon_app(83)
Exit BBTest(159)
Starting BBTest
Started BBTest(160)
Foreground BBTest(157)
My byte: 127 <------------
Foreground net_rim_bb_ribbon_app(83)
Exit BBTest(160)
Starting BBTest
Started BBTest(161)
Foreground BBTest(157)
My byte: 127 <------------
Foreground net_rim_bb_ribbon_app(83)
Exit BBTest(161)
--------------------------------------------------------
I have noticed something, if I remove the static push registries, the
application behaves normally and outputs -128 every time. An yes, I
have the same feeling that a MIDlet runs on top of a RIMlet, and in
the case the midlet defines push registries, the RIMlet is running all
the time. So my question now is, are there any solutions other than
initializing the static variables on every run (because there are
roughly >1000 such members in my app)
Yep, blackberry midlets retain the values of static variables. This is an issue, and the only way I see to fix it is that in the startup we need to assign null values to the static values. For example if a static var is declared like:
public static String State = null;
And in the life cycle of the middle the value is set to "closed";
Then in the next startup of the application, the value remains "closed" instead of null.
I guess you mean "in the second launch the static variables will not have the same values they had in previous run".
Static variables can only maintain their value through the lifetime of the app. The app ends when destroyApp()/notifyDestroyed() is called, so the values are lost!
To persist state over multiple runs, use the RecordStore.